Динамический курсор используется в блоке в TSQL? - PullRequest
0 голосов
/ 18 марта 2009

У меня есть следующие коды 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. закройте его.

В PL / SQL цикл может выглядеть следующим образом:

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

Это намного проще, чем мои коды TSQL. Нет необходимости определять курсор. Он создается динамически, который доступен внутри блока цикла (очень похоже на цикл C # for). Не уверен, есть ли что-то подобное в TSQL?

Ответы [ 5 ]

2 голосов
/ 18 марта 2009

Что-то в этом духе может работать для вас, хотя это зависит от наличия столбца идентификатора или другого уникального идентификатора

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 голос
/ 18 марта 2009

Курсоры - это зло в Sql Server, поскольку они действительно могут снизить производительность - мой любимый подход - использовать переменную таблицы (> = Sql Server 2005) со столбцом auto inc ID:

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

Это выглядит довольно долго, но работает в любой ситуации и должно быть намного легче, чем курсор

0 голосов
/ 23 марта 2009

Почему бы просто не вернуть набор записей с помощью оператора select. Я предполагаю, что цель состоит в том, чтобы скопировать и вставить значения в пользовательском интерфейсе (основываясь на том факте, что вы просто печатаете вывод)? В Management studio вы можете скопировать и вставить из сетки или нажать + T, а затем выполнить запрос и вернуть результаты в виде вкладки сообщений в виде простого текста.

Если вы запустите это через приложение, приложение не сможет получить доступ к печатным операторам, поскольку они не возвращаются в наборе записей.

0 голосов
/ 20 марта 2009

В некоторых случаях также можно использовать трюк, подобный этому:

DECLARE @name VARCHAR(MAX)

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

PRINT   @name

Список имен сотрудников.

Его также можно использовать для создания строки, разделенной запятыми, просто замените + CHAR (13) + CHAR (10) на + ','

0 голосов
/ 18 марта 2009

Поскольку вы пришли из среды Oracle, где курсоры используются часто, вы можете не знать, что в SQl Server курсоры снижают производительность. В зависимости от того, что вы действительно делаете (конечно, не просто печатаете переменную), может быть гораздо более быстрое решение на основе множеств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...