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

Getting Return Value from Dynamic SQL Upsert Stored Procedure

我有很多 table 具有相同的 (Something)ID tinyint,(Something)Name varchar(50) 的一般架构,如下所示:

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

我写了一个动态 sql 脚本,它可以在这些 table 上执行更新插入,给定 ID(如果不为 0 则更新,否则插入)、名称值和 table 姓名:

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

我想要 inserted/updated 项的 ID,并将其用作存储过程的 return 值。我该怎么做?

例如,如果我这样做

    EXEC UpsertListItemValue 1, 'Celluar Phone', PhoneType

我想恢复 1(更新后),如果我这样做了

    EXEC UpsertListItemValue 0, 'Work Phone', PhoneType

我想取回 3(插入后)。

使用SCOPE_IDENTITY获取插入的标识值

在动态-sql 脚本中使用 SCOPE_IDENTITY,因为它 returns 值在同一范围内。

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