带有tableName的SQL MERGE表

时间:2014-12-04 16:20:16

标签: sql sql-server tsql merge dynamic-sql

我希望有一个通用的程序来更新我的查找表。

CREATE TYPE S_Reference.[ReferenceType] as TABLE (
    [Id] SMALLINT NOT NULL PRIMARY KEY, 
    [Code] VARCHAR(16) UNIQUE NOT NULL, 
    [Rank] SMALLINT NOT NULL CHECK([Rank]>0),
    [Description] VARCHAR(128) NOT NULL,
    [Base] BIT NOT NULL DEFAULT 0);
GO

CREATE PROCEDURE [S_Reference].[P_B_ReferenceMerge]
    @Values [ReferenceType] READONLY,
    @TableName NVARCHAR(50)
AS

DECLARE @SQLQuery NVARCHAR(200)
SET @SQLQuery = 'SELECT * FROM ' + @TableName 

    MERGE INTO @SQLQuery Ori
    USING 
        @Values New
    ON (Ori.[Id] = New.[Id])
    WHEN MATCHED THEN
        UPDATE 
            SET Ori.[Code] = New.[Code],
                Ori.[Rank] = New.[Rank],
                Ori.[Description] = New.[Description],
                Ori.[Base] = New.[Base]
    WHEN NOT MATCHED THEN
        INSERT (Ori.[Id] , Ori.[Code], Ori.[Rank],Ori.[Description] ,Ori.[Base])
        Values (New.[Id] , New.[Code], New.[Rank],New.[Description] ,New.[Base]);
RETURN 0

但我不知道如何使用“tableName”? 我在Ori上收到错误。[Id],我认为问题来自

 SET @SQLQuery = 'SELECT * FROM ' + @TableName 
        MERGE INTO @SQLQuery Ori

1 个答案:

答案 0 :(得分:0)

如果可以帮助我这样做。通过这种方式,您可以轻松管理查找中的值(c#中的引用或枚举)。

首先是程序:

    CREATE TYPE S_Reference.[ReferenceType] AS TABLE (
    [Id] SMALLINT NOT NULL PRIMARY KEY, 
    [Code] VARCHAR(40) UNIQUE NOT NULL, 
    [Rank] SMALLINT UNIQUE NOT NULL CHECK([Rank]>0),
    [Description] VARCHAR(128) NOT NULL,
    [Base] BIT NOT NULL DEFAULT 0);
GO


CREATE PROCEDURE [S_Reference].[P_M_ReferenceMerge]
    @Values  S_Reference.[ReferenceType] READONLY,
    @TableName NVARCHAR(50)
AS

CREATE TABLE #NewValues (
    [Id] SMALLINT NOT NULL PRIMARY KEY, 
    [Code] VARCHAR(40) UNIQUE NOT NULL, 
    [Rank] SMALLINT UNIQUE NOT NULL CHECK([Rank]>0),
    [Description] VARCHAR(128) NOT NULL,
    [Base] BIT NOT NULL DEFAULT 0);

Insert INTO #NewValues
select * From @Values

DECLARE @SQLQuery NVARCHAR(MAX)
SET @SQLQuery = 
'DELETE 
FROM ' + @TableName + '
WHERE [Id] IN (SELECT [Id]
                FROM ' + @TableName + '
                EXCEPT
                SELECT [Id]
                FROM #NewValues)

MERGE INTO ' + @TableName + ' Ori 
USING #NewValues New 
ON (Ori.[Id] = New.[Id]) 
    WHEN MATCHED THEN 
    UPDATE 
        SET Ori.[Code] = New.[Code], 
        Ori.[Rank] = New.[Rank], 
        Ori.[Description] = New.[Description], 
        Ori.[Base] = New.[Base] 
    WHEN NOT MATCHED THEN 
    INSERT ([Id] , [Code], [Rank], [Description] ,[Base]) 
    Values (New.[Id] , New.[Code], New.[Rank], New.[Description] ,New.[Base]);'

EXEC sp_executesql @SQLQuery
RETURN 0

用法

INSERT INTO 
    @VALUES([Id],[Code],[Rank],[Description] ,[Base])
Values
    (1,'EUR',1,'EUR',0),
    (2,'GBP',2,'GBP',0),
    (3,'USD',3,'USD',0)
EXEC [S_Reference].[P_M_ReferenceMerge]
    @Values = @VALUES,
    @TableName = 'S_Reference.T_R_Currency'
DELETE FROM @VALUES