【问题标题】:Update new column with result set from stored procedure使用存储过程中的结果集更新新列
【发布时间】:2014-08-08 17:26:25
【问题描述】:

我有一个包含现有数据的表。我需要向表中添加一个新列,该列将填充使用存储过程检索的值。这对于我将要添加到表中的新数据来说很好。

如何为每个现有行运行存储过程,从两个现有列中传递参数,然后使用结果更新新列。实际上,我想运行以下内容:

UPDATE 
  TableWithNewColumn
SET
  NewColumn = EXEC NewProcedure(TableWithNewColumn.ID, TableWithNewColumn.Code);

在此处查看小提琴:http://www.sqlfiddle.com/#!3/b0625/1

我知道标量函数非常适合这项任务,但不幸的是 SP 是由第三方提供的,这是我提供数据的唯一方式。

【问题讨论】:

  • 我建议您使用内联 SQL 表达式,而不是为每一行调用一个 proc。您可以将表达式封装在标量函数中以实现可重用性。如果必须调用返回结果集的存储过程,则需要 1) 为源查询创建游标,2) 为每一行调用 proc,并将结果插入到临时表或表变量中,以及 3) 更新使用临时表/表变量的表。
  • @DanGuzman-SQLServerMVP 谢谢你,我认为游标将是遍历每条记录的方法。如果您能提供如何执行此操作的简短示例,我将不胜感激,因为我之前没有在 SQL Server 中使用过游标,只有 Oracle。如果需要,我会研究它,但如果你能让我开始,那将是一个很大的帮助。
  • 您不能从函数中调用存储过程。存储过程可以修改数据,并且不允许函数这样做。请参阅SO 上的此帖子以获取详细信息和请勿遵循的提示^^

标签: sql sql-server


【解决方案1】:

下面是一个游标示例,假设 id 列是唯一的。如果您可以更改存储的proc返回一个输出参数,您可以直接在update语句中使用输出参数,而不是将proc结果集插入到表变量和更新中的子查询中。

DECLARE
    @id int,
    @code varchar(16);

DECLARE @Result TABLE (
    ResultValue varchar(16)
    );

DECLARE TableRows CURSOR LOCAL FOR
    SELECT
        id
        ,code
    FROM dbo.TableWithNewColumn;
OPEN TableRows;
WHILE 1 = 1
BEGIN

    FETCH NEXT FROM TableRows INTO @id, @code;
    IF @@FETCH_STATUS = -1 BREAK;

    DELETE FROM @Result;
    INSERT INTO @Result EXEC dbo.NewProcedure @id, @code;

    UPDATE TableWithNewColumn
    SET NewColumn = (SELECT ResultValue FROM @Result)
    WHERE id = @id;

END;
CLOSE TableRows;
DEALLOCATE TableRows;

【讨论】:

    【解决方案2】:

    这是一个想法...用 ID、Code 和 NewColumn 结果的值填充 TEMP 表。然后通过连接到临时表来更新表 TableWithNewColumn。我建议这样做,因为使用所有这些过程调用进行更新会很慢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多