【问题标题】:Getting Return Value from Dynamic SQL Upsert Stored Procedure从动态 SQL Upsert 存储过程中获取返回值
【发布时间】:2016-02-12 09:54:01
【问题描述】:

我有很多表具有相同的 (Something)ID tinyint、(Something)Name 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(插入后)。

【问题讨论】:

    标签: sql sql-server dynamic-sql


    【解决方案1】:

    在动态 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
    

    【讨论】:

    • 正是我想要的。谢谢!
    【解决方案2】:

    使用SCOPE_IDENTITY 获取插入的标识值

    【讨论】:

    • 我尝试将RETURN @ItemIDRETURN SCOPE_IDENTITY() 添加到它们各自的块中,但我收到一条错误消息,提示“不能在此上下文中使用具有返回值的 RETURN 语句。”
    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 2013-01-22
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多