SQL中的块中使用的动态游标?

时间:2009-03-18 17:33:01

标签: sql sql-server sql-server-2005 tsql

我有以下TSQL代码:

-- 1. define a cursor
DECLARE c_Temp CURSOR FOR
    SELECT name FROM employees;

DECLARE @name varchar(100);
-- 2. open it
OPEN c_Temp;
-- 3. first fetch
FETCH NEXT FROM c_Temp INTO @name;
WHILE @@FETCH_STATUS = 0
BEGIN
  print @name;
  FETCH NEXT FROM c_Temp INTO @name; -- fetch again in a loop
END
-- 4. close it
....

我只在循环块中使用名称值。我必须在这里

  1. 定义游标变量
  2. 打开它,
  3. 取两次
  4. 关闭它。
  5. 在PL / SQL中,循环可以是这样的:

    FOR rRec IN (SELECT name FROM employees) LOOP
      DBMS_OUTPUT.put_line(rRec.name);
    END LOOP;
    

    它比我的TSQL代码简单得多。无需定义游标。它是动态创建的,可以在循环块中访问(很像C#for循环)。不确定在TSQL中是否有类似的东西?

5 个答案:

答案 0 :(得分:2)

这些行中的某些内容可能对您有用,但它取决于具有ID列或其他唯一标识符

Declare @au_id Varchar(20)
Select @au_id = Min(au_id) from authors

While @au_id IS NOT NULL
Begin
            Select au_id, au_lname, au_fname from authors Where au_id = @au_id
            Select @au_id = min(au_id) from authors where au_id > @au_id
End

答案 1 :(得分:1)

游标在Sql Server中是邪恶的,因为它们确实会降低性能 - 我最喜欢的方法是使用带有auto inc ID列的表变量(> = Sql Server 2005):

Declare @LoopTable as table (
     ID int identity(1,1),
     column1 varchar(10),
     column2 datetime
)
insert into @LoopTable (column1, column2)
select name, startdate from employees

declare @count int
declare @max int
select @max = max(ID) from @LoopTable 
select @count = 1

while @count <= @max
begin
   --do something here using row number '@count' from @looptable
   set @count = @count + 1
end

它看起来很长,但在任何情况下都可以工作,并且应该比光标更轻量级

答案 2 :(得分:0)

由于您来自经常使用游标的Oracle背景,您可能不知道在SQl Server中游标是性能杀手。根据您实际执行的操作(当然不仅仅是打印变量),可能会有一个更快的基于集合的解决方案。

答案 3 :(得分:0)

在某些情况下,它也可以像这样使用技巧:

DECLARE @name VARCHAR(MAX)

SELECT  @name = ISNULL(@name + CHAR(13) + CHAR(10), '') + name
FROM    employees

PRINT   @name

获取员工姓名列表。

它也可用于制作以逗号分隔的字符串,只需将 + CHAR(13)+ CHAR(10)替换为 +',

答案 4 :(得分:0)

为什么不直接使用select语句返回记录集。我假设对象是在UI中复制和粘贴值(基于您只是打印输出的事实)?在Management studio中,您可以从网格中复制和粘贴,或者按+ T然后运行查询并以纯文本形式将结果作为消息选项卡的一部分返回。

如果您通过应用程序运行此应用程序,则应用程序将无法访问打印的语句,因为它们未在记录集中返回。