Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
Пишу запрос. В нём планируется цикл в цикле:
Проходит один внутренний цикл и заносит значение в переменную таблицу @t1, после завершения n кол-ва проходов внутреннего цикла, значения таблицы @t1 заносится в таблицу во внешнем цикле @t2. После завершения k кол-ва внешних циклов. Внутренний цикл проходит без проблем (то есть 1 раз). Когда подключаю внешний - выходит ошибка "Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения".
Предлагаю подобный запрос, оригинал показать не могу по соображениям безопасности )

declare @@t1 table (bookcase int, shelf int, book varchar (100))
declare @@t2 table (bookcase int, shelf int, book varchar (100))
declare @@t3 table (bookcase int, shelf int, book varchar (100))
declare @@n int = 1
declare @@k int = 1
while @@k <=20 begin --кол-во шкафов с книгами
while @@n <=10 begin --кол-во полок в шкафу
insert into @@t1 (bookcase, shelf,book) select * from dbo.bookz where shelf = @@n and bookcase = @@k
insert into @@t1 (shelf,book) select count(book),'books_on_shelf' from @@t1
insert into @@t2 (bookcase, shelf,book) select * from @@t1
delete from @@t1
@@n = @@n + 1
end
insert into @@t2 (bookcase, shelf,book) select * from @@t1
insert into @@t2 (shelf,book) select count(book),'books_in_case' from @@t2 where bookcase is not null
insert into @@t3 (bookcase, shelf,book) select * from @@t2
delete from @@t2
@@k = @@k + 1
end
select * from @@t3;

Пробовал внутренний цикл не while а if - результат такой же. В чём причина такой ошибки? Так вообще можно?
15 дек 15, 11:56    [18561772]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
В чём причина такой ошибки?

В том, что после окончания вторго цикла переменная @@n останется равной 11.
Это отслеживается элементарным дебаггером
15 дек 15, 12:02    [18561818]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
Когда подключаю внешний - выходит ошибка "Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения".

Эта ошибка не зависит от наличия циклов
Это ошибка логики, написанного вами запроса
15 дек 15, 12:04    [18561827]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
СТУДЕНТ123
Guest
Вы прям маньяк циклический, задача исходная какая? зачем так издеваться над сервером?
15 дек 15, 12:05    [18561832]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Leran2002
Member

Откуда: Алматы, Казахстан
Сообщений: 53
Glory
Эта ошибка не зависит от наличия циклов
Это ошибка логики, написанного вами запроса

Да, сброс счетчика забыли сделать:
declare @@n int = 1
declare @@k int = 1
while @@k <=20 begin
  set @@n = 1 -- сброс
  while @@n <=10 begin
    print CAST(@@k AS varchar(2))+','+CAST(@@n AS varchar(2))
    set @@n = @@n + 1
  end
  set @@k = @@k + 1
end
15 дек 15, 12:07    [18561846]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
Ну, маньяк не маньяк, есть необходимость.
Ошибся немного, сброс счётчика в исходном запросе всё же есть внутри внешнего цикла. Ошибка ни куда не делась.
15 дек 15, 12:28    [18561977]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
Ошибка ни куда не делась.

Потому, что она не зависит от циклов. От слова совсем
15 дек 15, 12:29    [18561980]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
Glory,
дело в том, что когда я комментирую внешний цикл, всё работает:

declare @@t1 table (bookcase int, shelf int, book varchar (100))
declare @@t2 table (bookcase int, shelf int, book varchar (100))
declare @@t3 table (bookcase int, shelf int, book varchar (100))
declare @@n int = 1
declare @@k int = 1
--while @@k <=20 begin --кол-во шкафов с книгами
set @@n = 1
while @@n <=10 begin --кол-во полок в шкафу
insert into @@t1 (bookcase, shelf,book) select * from dbo.bookz where shelf = @@n and bookcase = @@k
insert into @@t1 (shelf,book) select count(book),'books_on_shelf' from @@t1
insert into @@t2 (bookcase, shelf,book) select * from @@t1
delete from @@t1
@@n = @@n + 1
end
insert into @@t2 (bookcase, shelf,book) select * from @@t1
insert into @@t2 (shelf,book) select count(book),'books_in_case' from @@t2 where bookcase is not null
insert into @@t3 (bookcase, shelf,book) select * from @@t2
delete from @@t2
--@@k = @@k + 1
--end
select * from @@t3;
15 дек 15, 12:35    [18562022]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
дело в том, что когда я комментирую внешний цикл, всё работает:

И еще раз
Ошибка
"Вложенный запрос вернул больше одного значения. Это запрещено, когда вложенный запрос следует после =, !=, <, <=, >, >= или используется в качестве выражения".

НЕ зависит от наличия циклов.

Она зависит от логики ваших "вложенных запросов". Которые "возвращают больше одного значения"
Ищите ваши вложенные запросы и исправляйте их.
15 дек 15, 12:37    [18562035]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
Чорт, почему не три собаки?
15 дек 15, 12:47    [18562097]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
Владислав Колосов,
Это глобальные переменные.
15 дек 15, 12:48    [18562105]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
Это глобальные переменные.

Да ладно. А если поставить @ @ @, то, наверное, переменная станет всемирной ?
15 дек 15, 12:50    [18562115]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Но лучше, конечно, пять звёздочек! ©
15 дек 15, 12:53    [18562141]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Leran2002
Member

Откуда: Алматы, Казахстан
Сообщений: 53
Возможно ваша задача решается GROUP BY с конструкциями ROLLUP или GROUPING SETS - читать...
15 дек 15, 13:02    [18562197]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
Glory,

Не помню от куда, но у меня была вера в то, что переменные @имя - локальные (в рамках одного select), а @@имя - глобальные ( по всему запросу). Поменял @@ на @ - ничего не изменилось (в смысле на рабочих запросах). Разрыв шаблона...
15 дек 15, 13:23    [18562322]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
Не помню от куда, но у меня была вера в то, что переменные @имя - локальные (в рамках одного select), а @@имя - глобальные ( по всему запросу). Поменял @@ на @ - ничего не изменилось (в смысле на рабочих запросах). Разрыв шаблона...

Потому что все _встроенные_ глобальные переменные начинаются с @@. И то правильно их называть не переменными, а функциями.
15 дек 15, 13:28    [18562372]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
Нашёл ошибку. У меня кол-во полок задаётся не цифрой 10 (написал для упрощения), а значениями из таблици, вида | number | shelf |, которая заполнялась значениями заново по каждому шкафу. Во внешнем цикле нужно опустошать эту таблицу, прежде чем переходить к следующему шкафу. Иначе, с одинаковыми номерами выпадают несколько полок.
16 дек 15, 09:46    [18566201]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Glory
Member

Откуда:
Сообщений: 104751
panick
Во внешнем цикле нужно опустошать эту таблицу, прежде чем переходить к следующему шкафу

Нужно запрос писать правильно. Чтобы он возвращал ОДНО значение.
16 дек 15, 09:54    [18566225]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
panick
Нашёл ошибку. У меня кол-во полок задаётся не цифрой 10 (написал для упрощения), а значениями из таблици, вида | number | shelf |, которая заполнялась значениями заново по каждому шкафу. Во внешнем цикле нужно опустошать эту таблицу, прежде чем переходить к следующему шкафу. Иначе, с одинаковыми номерами выпадают несколько полок.
10 - это цифра? Не знал...
Думал, что это две цифры.

Что-то мне подсказывает, что не нужны здесь циклы.
16 дек 15, 10:32    [18566395]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Не нужны тут ни циклы, ни промежуточные таблицы.
declare @t table (bookcase int, shelf int, book varchar(100));

insert into @t
values
 (1, 1, 'book1'),
 (1, 1, 'book2'),
 (1, 2, 'book3'),
 (1, 2, 'book4'),
 (1, 2, 'book5'),
 (2, 1, 'book6'),
 (2, 1, 'book7'),
 (2, 2, 'book8'),
 (2, 3, 'book9');

select
 case when grouping(shelf) = 1 or grouping(book) = 1 then null else bookcase end as bookcase,
 case when grouping(shelf) = 1 or grouping(book) = 1 then count(*) else shelf end as shelf,
 case when grouping(shelf) = 1 then 'books_in_case' when grouping(book) = 1 then 'books_on_shelf' else book end as book
from
 @t
group by
 grouping sets((bookcase, shelf, book), (bookcase, shelf), (bookcase));
16 дек 15, 11:05    [18566615]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
panick
Владислав Колосов,
Это глобальные переменные.




отлично, будем знать
16 дек 15, 11:47    [18566931]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
panick
Нашёл ошибку. У меня кол-во полок задаётся не цифрой 10 (написал для упрощения), а значениями из таблици, вида | number | shelf |, которая заполнялась значениями заново по каждому шкафу. Во внешнем цикле нужно опустошать эту таблицу, прежде чем переходить к следующему шкафу. Иначе, с одинаковыми номерами выпадают несколько полок.


зы. 10 - это число
16 дек 15, 12:06    [18567038]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
panick
Member

Откуда:
Сообщений: 12
invm, похоже для этого запроса циклы действительно не нужны. Но, это только макет. В реальном запросе, с каждым результатом прохода цикла, выполняются ещё несколько действий, результатом которых являются ещё 3 строки, которые добавляются снизу к татлице t1.

Спасибо всем, кто проявил участие. Это был мой первый опыт обращения за помощью на форуме. Думаю, последний. Некоторые советы были дельными. В основном же, пришёл к выводу, что гораздо эффективнее курить мануалы самому, чем кормит троллей на форумах.
16 дек 15, 15:38    [18568443]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
panick
Спасибо всем, кто проявил участие. Это был мой первый опыт обращения за помощью на форуме. Думаю, последний. Некоторые советы были дельными. В основном же, пришёл к выводу, что гораздо эффективнее курить мануалы самому, чем кормит троллей на форумах.

ну почти правильные выводы, однако
Тока сначала курят мануалы..потогм пробуют ,а если савсем затык то спрашивают
любой другой порядок - гарантирует флудд
16 дек 15, 15:56    [18568558]     Ответить | Цитировать Сообщить модератору
 Re: возможен ли цикл в цикле?  [new]
mishanya3624
Member

Откуда:
Сообщений: 796
panick,

ну а что ты думал, все же люди, а не альтруисты роботизированные, всем нужно водки и блэкджека иногда:)
16 дек 15, 16:58    [18568902]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить