SQL:如何使存储过程中的表名动态化

3
我对 SQL Server 还比较陌生,希望这里有人能帮我(我使用的是 SQL Server 2008)。
以下是一个小程序,它可以按预期运行。
现在我想使用相同的过程来更新多个表,因为所有这些表都具有完全相同的列名和列格式,唯一的区别是表名称的第二部分,在此处添加了“XXX”。
有人能告诉我如何使其具有动态性并为我提供一些解释吗? 我无法提供更多信息,因为我不确定该如何处理 - 除了可能声明 '@sql nvarchar(max)' 并将整个查询包装在 'SET @sql = N'...' ' 中以便执行。
我的存储过程:
    CREATE PROCEDURE [dbo].[Cal_UpdateTeam]
        @team nvarchar(100),
        @teamID int,
        @notes nvarchar(1000),
        @log nvarchar(100),
        @admin varchar(50)
    AS
    BEGIN
        SET NOCOUNT ON;

        BEGIN   

        IF NOT EXISTS 
        (
                SELECT  * 
                FROM    Cal_XXX
                WHERE   teamID = @teamID
        )
        INSERT INTO Cal_XXX
        (
                team,
                teamID,
                notes,
                log,
                admin
        )
        SELECT  @team,
                @teamID,
                @notes,
                @log,
                @admin
        ELSE
                UPDATE  Cal_XXX
                SET     team = @team,
                        teamID = @teamID,
                        notes = @notes,
                        log = @log,
                        admin = @admin
                WHERE   teamID = @teamID

        END
END

非常感谢您对此的任何建议和意见,Mike。

4
所有这些表格都有完全相同的列名和列格式。通常这是数据库设计不良的标志。你应该只有一个表格,用一列来区分“XXX”。如果你的设计良好,那么你就不会为这个存储过程而苦苦挣扎。 - Gordon Linoff
1
可能是SQL Server存储过程中的动态数据源的重复问题。 - pritaeas
@GordonLinoff:谢谢你。是的,它们都有相同的列名,但其中一些有不需要的额外列,这些列对我的查询没有用处。 - Mike
1
@Mike:公共属性应该在一个公共表中;特定属性应该在子类型表中。 - Pieter Geerkens
谢谢,两位。我不确定将所有这些表合并成一个是否有意义,因为它们用于生成导航栏,其中每个级别的导航栏都有自己的表,并且它们彼此链接,因为每个级别在下一级别上有子级。如果我将它们合并,那么链接将在同一个表内。 - Mike
2个回答

8

您需要将SQL查询语句包装在nvarchar中,然后按照以下示例执行该查询:

    declare @sql nvarchar(max)
    declare @TableName nvarchar(max)
    set @TableName = 'mytable'
    set @sql = 'Select * from ' + @TableName
    Exec sp_executesql @sql

这对我有用。应该将其标记为被接受的答案。 - smartexpert

0

在SP中,您可以使用临时表,例如:

CREATE PROCEDURE SELECT_TABLE
    @REQUEST_ID INT
AS
BEGIN

/*************************************
** Temporary table                  **
*************************************/
    CREATE TABLE #SOURCE (
        ID        INT
      , ID_PARENT INT
      , NAME      VARCHAR(200)
      , SORT      INT
      ..
      ..
    )

IF @REQUEST_ID = 'YES' BEGIN
    INSERT INTO #SOURCE SELECT * FROM SOURCE_A
END
ELSE BEGIN
    INSERT INTO #SOURCE SELECT * FROM SOURCE_B
END

SELECT * FROM #SOURCE
.....


END

GO

在存储过程中,您可以使用参数来封装其他具有不同表名的存储过程:

CREATE PROCEDURE SELECT_FROM_TABLE_A
AS
BEGIN
    SELECT * FROM SOURCE_A
END
GO
CREATE PROCEDURE SELECT_FROM_TABLE_B
AS
BEGIN
    SELECT * FROM SOURCE_B
END
GO

CREATE PROCEDURE SELECT_TABLE
    @REQUEST_ID INT

AS
BEGIN

/**********************************************
** Subrequest select                         **
**********************************************/

    IF @REQUEST_ID = 'YES' BEGIN
        -- Request SP fro Source A
        EXEC SELECT_FROM_TABLE_A
    END
    ELSE
    BEGIN
        -- Request SP fro Source B
        EXEC SELECT_FROM_TABLE_B
    END
END
GO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接