powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Курсор в курсоре
23 сообщений из 23, страница 1 из 1
Курсор в курсоре
    #33598801
Фотография VladislavVV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем добрый день

Кто нибуть работал с курсором в курсоре?
Работает ли?
Есть ли подводные камни?

Спасибо за ответы.

MS SQL 2000
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598839
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я работал.
Работает.
Есть.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598853
Crimean
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а что, сложно сделать cross join и один курсор ? :)
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598885
Фотография daw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BOL - Declare cursor - Examples: B. Use nested cursors to produce report output


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598897
Фотография VladislavVV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pkarklinЯ работал.
Работает.
Есть.

какие-если не секрет?
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598908
Фотография VladislavVV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Crimeanа что, сложно сделать cross join и один курсор ? :)

там хитрая идея-просто так не получится
просто если есть глюки в курсор в курсоре- то прийдется обойтись
другм, более тормознутым но 100% действ рез-том
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598912
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычно до этого абзаца статьи раздела DECLARE CURSOR не дочитывают:

авторVariables may be used as part of the select_statement that declares a cursor. Cursor variable values do not change after a cursor is declared. In SQL Server version 6.5 and earlier, variable values are refreshed every time a cursor is reopened.

Т.е. вложенный курсор нужно бязательно декларировать внутри внешнеого.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #33598924
Фотография VladislavVV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pkarklinОбычно до этого абзаца статьи раздела DECLARE CURSOR не дочитывают:

авторVariables may be used as part of the select_statement that declares a cursor. Cursor variable values do not change after a cursor is declared. In SQL Server version 6.5 and earlier, variable values are refreshed every time a cursor is reopened.

Т.е. вложенный курсор нужно бязательно декларировать внутри внешнеого.

т.е. как в примере

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
обьявили К1
фетч к1
...
обьявили К2
фетч к2

...

закрыли К2
закрыли К1


других камней нет?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Курсор в курсоре
    #39786182
TheKLF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
простите, что поднимаю "мертвую" тему, но можно ли пример кода "курсор в курсоре"

допустим такого вида: есть таблица с некими значениями(таблица 1), которые будем использовать для конструкции запроса и есть таблица с элементами(таблица 2), которые надо проверить на наличие в общей БД

Код: sql
1.
SELECT * FROM 'параметр из таблицы 1' WHERE [field] like 'параметр из таблицы 2'
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786185
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TheKLF,

вложенные курсоры прям в документации описаны

B. Using nested cursors
https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql?view=sql-server-2017
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786205
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKTheKLF,

вложенные курсоры прям в документации описаны

B. Using nested cursors
https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql?view=sql-server-2017

Прочитал три раза. А что там "вложенного" то?
Так можно и десять курсоров "вложить".
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786224
Фотография SIMPLicity_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222TaPaKTheKLF,

вложенные курсоры прям в документации описаны

B. Using nested cursors
https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql?view=sql-server-2017

Прочитал три раза. А что там "вложенного" то?
Так можно и десять курсоров "вложить".

Экзампл Би: B. Using nested cursors to produce report output

Или это был "САРКАЗМ"
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786262
TheKLF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо большое за ответы!

вот мой способ решения задачи "Курсор в Курсоре"

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
--проверяем наличие первой временной таблицы, если она существует - то удаляем её
if OBJECT_ID('tempdb..#TempTable') is not null
begin
	drop table #TempTable
end
--проверяем наличие второй временной таблицы, если она существует - то удаляем её
if OBJECT_ID('tempdb..#TempTableCodes') is not null
begin
	drop table #TempTableCodes
end

select [name] 
INTO #TempTable
FROM sys.objects WHERE type in (N'U') and [name] LIKE 'StoreRetail_number_%' ORDER BY [name]
print 'сколько нашли магазинов'

--создаём таблицу для данных, которые мы загрузим из файла
create table #TempTableCodes
(
[name] nvarchar(30)
)
--из внешнего файла загружаем значения для обработки
bulk insert #TempTableCodes
	from 'd:\codes_search.txt'
	with (ROWTERMINATOR = '\n')

print 'контроль работы'

select * from #TempTableCodes
print ' #TempTableCodes'
select * from #TempTable
print ' #TempTable'
print ' '
print ' '

declare @code nvarchar(30)
declare @table nvarchar (50)
declare @mySel nvarchar (500)

--объявляем первый курсор
declare @CursorTables CURSOR
--заполняем его значениями временной таблицы
set @CursorTables = CURSOR for
	select * from #TempTable
open @CursorTables

	fetch next from @CursorTables into @table
	while @@FETCH_STATUS = 0
	begin
			print ' Блок - @CursorTables'
                                --объявляем второй курсор
				declare @CursorCodeTables CURSOR
                                --заполняем его из нужной ему временной таблицы
				set @CursorCodeTables = CURSOR local for
				select * from #TempTableCodes
				open @CursorCodeTables

					fetch next from @CursorCodeTables into @code
					while @@FETCH_STATUS = 0
						begin
							--формируем запрос к БД
							set @mySel = 'SELECT [Store],[Product],[Item],[Seller],[Orders] FROM ' +@table+ ' WHERE [Orders] like ''%' + @code + '%'''
							print 'контроль как выглядит мой запрос=  '+@mySel
                                                        --выполняем запрос к БД
							EXEC sp_executesql @mySel
							fetch next from @CursorCodeTables into @code
			                        end
                     fetch next from @CursorTables into @table
	end

	close @CursorCodeTables
	deallocate @CursorCodeTables

	close @CursorTables
	deallocate @CursorTables

...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786292
Фотография SIMPLicity_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TheKLFСпасибо большое за ответы!

вот мой способ решения задачи "Курсор в Курсоре"

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
--проверяем наличие первой временной таблицы, если она существует - то удаляем её
if OBJECT_ID('tempdb..#TempTable') is not null
begin
	drop table #TempTable
end
--проверяем наличие второй временной таблицы, если она существует - то удаляем её
if OBJECT_ID('tempdb..#TempTableCodes') is not null
begin
	drop table #TempTableCodes
end

select [name] 
INTO #TempTable
FROM sys.objects WHERE type in (N'U') and [name] LIKE 'StoreRetail_number_%' ORDER BY [name]
print 'сколько нашли магазинов'

--создаём таблицу для данных, которые мы загрузим из файла
create table #TempTableCodes
(
[name] nvarchar(30)
)
--из внешнего файла загружаем значения для обработки
bulk insert #TempTableCodes
	from 'd:\codes_search.txt'
	with (ROWTERMINATOR = '\n')

print 'контроль работы'

select * from #TempTableCodes
print ' #TempTableCodes'
select * from #TempTable
print ' #TempTable'
print ' '
print ' '

declare @code nvarchar(30)
declare @table nvarchar (50)
declare @mySel nvarchar (500)

--объявляем первый курсор
declare @CursorTables CURSOR
--заполняем его значениями временной таблицы
set @CursorTables = CURSOR for
	select * from #TempTable
open @CursorTables

	fetch next from @CursorTables into @table
	while @@FETCH_STATUS = 0
	begin
			print ' Блок - @CursorTables'
                                --объявляем второй курсор
				declare @CursorCodeTables CURSOR
                                --заполняем его из нужной ему временной таблицы
				set @CursorCodeTables = CURSOR local for
				select * from #TempTableCodes
				open @CursorCodeTables

					fetch next from @CursorCodeTables into @code
					while @@FETCH_STATUS = 0
						begin
							--формируем запрос к БД
							set @mySel = 'SELECT [Store],[Product],[Item],[Seller],[Orders] FROM ' +@table+ ' WHERE [Orders] like ''%' + @code + '%'''
							print 'контроль как выглядит мой запрос=  '+@mySel
                                                        --выполняем запрос к БД
							EXEC sp_executesql @mySel
							fetch next from @CursorCodeTables into @code
			                        end
                     fetch next from @CursorTables into @table
	end

	close @CursorCodeTables
	deallocate @CursorCodeTables

	close @CursorTables
	deallocate @CursorTables



Студия ошибок не дала (запускать не стал, только смотрел анализ кода), но мне почему-то кажется, что вот это

Код: sql
1.
2.
	close @CursorCodeTables
	deallocate @CursorCodeTables



должно стоять непосредственно перед

Код: sql
1.
fetch next from @CursorTables into @table
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786298
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то модно стало объявлять declare @CursorTables CURSOR. Или это из одной бочки решения копипастом.
Это лишь бы LOCAL не написать, что ли? Или для крутости все переменные согнать в начало процедуры?
Ошибка появится во время выполнения при повторном открытии курсора.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786465
TheKLF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов,

спасибо за ответ!

А можно чуть подробнее объяснить ваш ответ.
Это не copy-paste, просто на всех форумах одно и тоже написано.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786488
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TheKLF,

Курсоры тут нафиг не нужны:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
if OBJECT_ID('tempdb..#TempTableCodes') is not null
begin
	drop table #TempTableCodes
end;

create table #TempTableCodes
(
[name] nvarchar(30)
);

--из внешнего файла загружаем значения для обработки
bulk insert #TempTableCodes
	from 'd:\codes_search.txt'
	with (ROWTERMINATOR = '\n');

declare @sql nvarchar(max);

select
 @sql = t.x.value('.', 'nvarchar(max)')
from
 (
  select
   N'SELECT a.[Store],a.[Product],a.[Item],a.[Seller],a.[Orders] FROM ' + quotename(schema_name(schema_id))) + N'.' + quotename(name) +
   N' a WHERE exist(select * from #TempTableCodes b where a.[Orders] like ''%'' + b.name + ''%'');'
  FROM sys.objects WHERE type in (N'U') and [name] LIKE 'StoreRetail_number_%' ORDER BY [name]
  for xml path('')
 ) t(x);

exec sp_executesql @sql;



В дальнейшем возможно осознаете, что подход "для каждого магазина - своя таблица" также ущербен.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786490
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TheKLFА можно чуть подробнее объяснитьВариант с переменной
Код: sql
1.
2.
3.
declare @CursorTables CURSOR
set @CursorTables = CURSOR for
	select * from #TempTable

Эквивалентен варианту
Код: sql
1.
2.
declare CursorTables CURSOR LOCAL 
	select * from #TempTable


Но в первом варианте можно разнести declare и set снаружи и внутри цикла, и тогда получится ошибка.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786510
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgВариант с переменной
Код: sql
1.
2.
3.
declare @CursorTables CURSOR
set @CursorTables = CURSOR for
	select * from #TempTable


Эквивалентен варианту
Код: sql
1.
2.
declare CursorTables CURSOR LOCAL 
	select * from #TempTable



Они эквивалентны, если свойство CURSOR_DEFAULT БД = LOCAL

... а оно, имхо, по умолчанию - GLOBAL
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786517
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtОни эквивалентны, если свойство CURSOR_DEFAULT БД = LOCALА, точно
BOLThe syntax rules for SET @cursor_variable do not include the LOCAL and GLOBAL keywords. When the SET @cursor_variable = CURSOR... syntax is used, the cursor is created as GLOBAL or LOCAL, depending on the setting of the default to local cursor database option.Я то думал, с переменной он всегда получается LOCAL (никогда не использовал курсорные переменные)

Значит, вообще так нельзя писать, ибо непонятно, что получишь.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39786743
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
court,

тип курсора по умолчанию определён в свойствах базы данных. Можно указать явно при создании базы или свойство копируется из базы model.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39791076
TheKLF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,

Спасибо большое!!! А не будет вам в большую тягость чуть расшифровать ваш код. Как оно работает



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare @sql nvarchar(max);

select
 @sql = t.x.value('.', 'nvarchar(max)')
from
 (
  select
   N'SELECT a.[Store],a.[Product],a.[Item],a.[Seller],a.[Orders] FROM ' + quotename(schema_name(schema_id))) + N'.' + quotename(name) +
   N' a WHERE exist(select * from #TempTableCodes b where a.[Orders] like ''%'' + b.name + ''%'');'
  FROM sys.objects WHERE type in (N'U') and [name] LIKE 'StoreRetail_number_%' ORDER BY [name]
  for xml path('')
 ) t(x);
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39791085
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо ещё обратить внимание, что курсор по умолчанию ДИНАМИЧЕСКИЙ!
Так что будьте осторожны!
Все изменения в таблицах, на которых построен курсор, моментально отражаются в курсоре!
Например, если имеется ORDER BY, то изменённая запись может снова оказаться впереди
текущей позиции курсора и обработаться ещё раз. Вплоть до бесконечного цикла.
Обычно эту причину зацикливания не так-то просто найти.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Курсор в курсоре
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]