0

我有一个存储过程

DECLARE cursor FOR SELECT [FooData] From [FooTable];
OPEN cursor ;  
FETCH NEXT FROM cursor INTO @CurrFooData;
WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT @CurrFooData AS FooData;
  INSERT INTO Bar (BarData) VALUES(@CurrFooData);
  FETCH NEXT FROM cursor INTO @CurrFooData;
END;
CLOSE cursor 
DEALLOCATE cursor 

但结果我有很多桌子,没有一张。如何返回一个包含“FooData”列和所有“@CurrFooData”行的表?

4

2 回答 2

1

德米特里,我认为你真的应该试着一起摆脱那个光标。在第二个示例中,您选择了两个字段FooData1FooData2,但最后,您只插入了值....

您可以轻松地重写第二个查询 - 例如:

INSERT INTO Bar (BarData) 
    SELECT FooData1 FROM FooTable

这就是你的整个光标和一切都在做的事情。

不惜一切代价尽量避免使用游标——99% 的情况下,它们是不需要的——开始考虑数据集——不要坚持使用 SQL 中的过程循环和游标——这不是一个很好的匹配!

如果您需要输出刚刚插入的内容,请使用以下OUTPUT子句:

INSERT INTO Bar (BarData) 
    OUTPUT Inserted.* 
    SELECT FooData1 FROM FooTable
于 2010-04-04T16:00:16.267 回答
1

是不是要输出刚刚插入的数据?如果是这种情况,并且您使用的是SQL Server 2005之前的 SQL Server 版本,那么您可以将所需的值填充到临时表中,如下所示:

Create Table #FooTemp ( FooData ... )

Insert #FooTemp( FooData )
Select FooData
From FooTable

Insert Bar( BarData )
Select FooData
From #FooTemp

Select FooData
From #FooTemp

这种方法的缺点是,由于临时表的原因,它可能会在每次运行存储过程时导致重新编译。

如果您使用的是 SQL Server 2000+,则只能在表变量中执行与上述相同的操作:

Declare @FooTemp Table ( FooData ... )

Insert @FooTemp( FooData )
Select FooData
From FooTable

Insert Bar( BarData )
Select FooData
From @FooTemp

Select FooData
From @FooTemp

如果您使用的是 SQL Server 2005+,则可以像这样使用 OUTPUT 子句:

Insert Bar( BarData )
 OUTPUT inserted.BarData
Select FooData
From FooTable
于 2010-04-04T16:59:56.713 回答