从存储过程结果集中插入/更新表中的数据

问题描述

|| 我有一个称为proc_item的存储过程,该过程从不同的表中获取数据(使用连接)。我希望存储过程的结果集可以在另一个称为Item的表上插入(如果数据是新的)或更新(如果数据已经存在)。谁能给我一些有关如何执行此操作的想法?我是sql,存储过程和循环程序的新手。 谢谢     

解决方法

        看一下@srutzky \的解决方案,它更适合此问题 您可以做的第一件事是将所有内容写入表中。 为此,您需要定义一个表,该表具有与存储过程返回的列相同的列:
DECLARE @myTempTableName TABLE(
                                dataRow1 DATATYPE,dataRow2 DATATYPE,...
                               )

INSERT INTO @myTempTableName(dataRow1,dataRow2,...)
EXEC( *mystoredprocedure* )
现在,您需要的所有数据都在表中。下一步是检查您需要更新什么以及要插入什么。假设datarow1是用于检查其是否已经存在的变量(例如:相同的名称或相同的ID),并说它是唯一的(否则您还需要某些巫婆是唯一的-需要遍历临时表)
DECLARE @rows INT,@dataRow1 DATATYPE,@dataRow2 DATATYPE,...

-- COUNT Nr. of rows (how many rows are in the table)
SELECT 
    @rows = COUNT(1) 
FROM 
    @myTempTableName 

-- Loop while there are still some rows in the temporary table
WHILE (@rows > 0)

BEGIN

  -- select the first row and use dataRow1 as indicator which row it is. If dataRow1 is not unique the index should be provided by the stored procedure as an additional column
  SELECT TOP 1
    @dataRow1 = dataRow1,@dataRow2 = dataRow2,..
  FROM
    @myTempTableName

  -- check if the value you\'d like to insert already exists,if yes --> update,else --> insert
  IF EXISTS (SELECT * FROM *TableNameToInsertOrUpdateValues* WHERE dataRow1=@dataRow1)
      UPDATE 
            *TableNameToInsertOrUpdateValues*
      SET
            dataRow2=@dataRow2
      WHERE
            dataRow1=@dataRow1

  ELSE
      INSERT INTO 
            *TableNameToInsertOrUpdateValues* (dataRow1,dataRow2)
      VALUES 
            (@dataRow1,@dataRow2)


  --IMPORTANT: delete the line you just worked on from the temporary table
  DELETE FROM 
     @myTempTableName 
  WHERE 
     dataRow1= @dataRow1

  SELECT 
     @rows = COUNT(1) 
  FROM 
     @myTempTableName

END -- end of while-loop
声明可以在此查询的开头完成。我将其放在使用它的地方,以便于阅读。 我从中获取代码的一部分,并且对遍历表有帮助(来自@cmsjr的解决方案,不带游标):游标内的游标     ,        您应该创建一个临时表来保存存储过程的结果,然后将结果合并到表中。建议在表变量上使用临时表,因为由于更好的统计信息,它将更好地与现有表结合。
CREATE TABLE #TempResults
(
  Field1 DATATYPE1,Field2 DATATYPE2,...,PRIMARY KEY CLUSTERED (KeyField1,...)
)

INSERT INTO #TempResults (Field1,Field2,...)
   EXEC Schema.ProcName @Param1,...
现在,有两种方法可以进行合并。第一个适用于所有版本的SQL Server,第二个使用SQL Server 2008中引入的命令。
-- this should work on all SQL SERVER versions
UPDATE  rt
SET     rt.Field2 = tmp.Field2,...
FROM    Schema.RealTable rt
INNER JOIN   #TempResults tmp
        ON   tmp.KeyField1 = rt.KeyField1
        ...

INSERT INTO Schema.RealTable (Field1,...)
   SELECT  tmp.Field1,tmp.Field2,...
   FROM    #TempResults tmp
   LEFT JOIN  Schema.RealTable rt
          ON  rt.KeyField1 = tmp.KeyField1
          ...
   WHERE   rt.KeyField1 IS NULL
要么:
-- the MERGE command was introduced in SQL SERVER 2008
MERGE Schema.RealTable AS target
USING (SELECT Field1,... FROM #TempResults) AS source (Field1,..)
ON (target.KeyField1 = source.KeyField1)
WHEN MATCHED THEN 
  UPDATE SET Field2 = source.Field2,...
WHEN NOT MATCHED THEN   
  INSERT (Field1,...)
     SELECT  tmp.Field1,...
     FROM    #TempResults tmp
有关MERGE命令的更多信息,请转到此处: http://msdn.microsoft.com/zh-CN/library/bb510625(v=SQL.100).aspx 现在,如果要合并的结果集很大,并且要合并的表很大,并且其中有很多活动,而这种操作可能会导致某些阻塞,那么可以循环执行以形成1000行的集合一次或类似的时间。与此类似:
<insert CREATE TABLE / INSERT...EXEC block>

CREATE TABLE #CurrentBatch
(
  Field1 DATATYPE1,...
)

DECLARE @BatchSize SMALLINT = ????

WHILE (1 = 1)
BEGIN

    -- grab a set to work on
    DELETE TOP (@BatchSize)
    OUTPUT deleted.Field1,deleted.Field2,...
    INTO #CurrentBatch (Field1,...)
    FROM #TempResults

    IF (@@ROWCOUNT = 0)
    BEGIN
        -- no more rows
        BREAK
    END

    <insert either UPDATE / INSERT...SELECT block or MERGE block from above
     AND change references to #TempResults to be #CurrentBatch>

    TRUNCATE TABLE #CurrentBatch

END
    ,        您首先需要将数据插入临时容器(例如临时表或表变量)中。然后,您可以像往常一样使用该表:将其连接,从中导出结果集等。 检查此问题以获取用于将SP的输出存储到表中的选项。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...