从动态SQL Upsert存储过程获取返回值

时间:2016-02-11 22:33:05

标签: sql sql-server dynamic-sql

我有很多表使用相同的通用架构(Something)ID tinyint,(Something)名称varchar(50)是这样的:

            PhoneType
    ---------------------------
    PhoneTypeID | PhoneTypeName
    ---------------------------
          1     |  Cell Phone
          2     |  Landline  

我编写了一个动态sql脚本,可以对这些表进行upsert,给定ID(如果不是0则更新,否则插入),名称值和表名:

ALTER PROCEDURE [dbo].[UpsertListItemValue] 
            @ItemID varchar(4),
            @ItemName varchar(50),
            @TableName varchar(50)
AS

DECLARE @sql nvarchar(500)

SET @sql = 'IF ' + @ItemID + ' <> 0
BEGIN
    UPDATE ' + @TableName + '
       SET ' + @TableName + 'Name = ''' + @ItemName + '''
    WHERE ' + @TableName + 'ID = ' + @ItemID + '
END
ELSE
BEGIN
    INSERT INTO ' + @TableName + '
       (' + @TableName + 'Name)
     VALUES
       (''' + @ItemName + ''')
END'
EXECUTE (@sql)
GO

我想要插入/更新项目的ID,并将其用作我的存储过程的返回值。我该怎么做?

例如,如果我这样做

    EXEC UpsertListItemValue 1, 'Celluar Phone', PhoneType

我想让1回来(更新后),如果我做了

    EXEC UpsertListItemValue 0, 'Work Phone', PhoneType

我希望得到3(插入后)。

2 个答案:

答案 0 :(得分:3)

在dynamic-sql脚本中使用SCOPE_IDENTITY,因为它返回相同范围内的值。

alter PROCEDURE [dbo].[UpsertListItemValue] 
            @ItemID varchar(4),
            @ItemName varchar(50),
            @TableName varchar(50)
AS

DECLARE @sql nvarchar(500)
      , @ret tinyint

SET @sql = 'IF ' + @ItemID + ' <> 0
BEGIN
    UPDATE ' + @TableName + '
       SET ' + @TableName + 'Name = ''' + @ItemName + '''
    WHERE ' + @TableName + 'ID = ' + @ItemID + '
END
ELSE
BEGIN
    INSERT INTO ' + @TableName + '
       (' + @TableName + 'Name)
     VALUES
       (''' + @ItemName + ''')
END

SET @ret = isnull(SCOPE_IDENTITY(), ''' + @ItemID + ''')'

EXECUTE SP_EXECUTESQL @sql, N'@ret tinyint OUTPUT', @ret = @ret output

RETURN @ret
GO

答案 1 :(得分:0)

使用SCOPE_IDENTITY来获取插入的标识值