Цикл WHILE для выбора данных за период в T-SQL — Разработка на vc.ru
Зачастую в нашей работе возникает потребность получить набор данных за определенный период. Сделать это можно несколькими способами. В этой статье рассмотрим применение цикла WHILE для задачи поиска расходных операций за несколько месяцев по перечню счетов и сравним его с запросом, в котором весь период будет указан в блоке WHERE.
4180 просмотров
Зачастую в нашей работе возникает потребность получить набор данных за определенный период. Сделать это можно несколькими способами. В этой статье рассмотрим применение цикла WHILE для задачи поиска расходных операций за несколько месяцев по перечню счетов и сравним его с запросом, в котором весь период будет указан в блоке WHERE.
Для начала разберем синтаксис конструкции WHILE. Выглядит он следующим образом:
WHILE [логическое условие] BEGIN [инструкция] END
В блоке Условие находится выражение, возвращающее значение TRUE или FALSE, в блоке Инструкций будет находиться наш запрос на выбор необходимого набора данных.
Теперь рассмотрим на примере применение цикла WHILE и сравним его с простым запросом. Для начала создадим таблицы для перечня счетов (1000 счетов с движением средств), результатов простого запроса и результатов цикла WHILE.
CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_accounts] ( [account_nbr] nvarchar(255) ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_query] ( [DEPOHIST_ID_MAJOR] bigint ,[DEPOHIST_ID_MINOR] bigint ,[DEPOHIST_ID_MEGA] bigint ,[DEPOSIT_ID_MAJOR] bigint ,[DEPOSIT_ID_MINOR] bigint ,[DEPOSIT_ID_MEGA] bigint ,[PERSON_ID_MAJOR] bigint ,[PERSON_ID_MINOR] bigint ,[PERSON_ID_MEGA] bigint ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_while] ( [DEPOHIST_ID_MAJOR] bigint ,[DEPOHIST_ID_MINOR] bigint ,[DEPOHIST_ID_MEGA] bigint ,[DEPOSIT_ID_MAJOR] bigint ,[DEPOSIT_ID_MINOR] bigint ,[DEPOSIT_ID_MEGA] bigint ,[PERSON_ID_MAJOR] bigint ,[PERSON_ID_MINOR] bigint ,[PERSON_ID_MEGA] bigint ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO
Информация об операциях в нашем случае хранится в [backoffice_STG]. [deposit].[VW_depohist], где созданы индексы на номер счета ([deposit_printableno]) и дату операции ([depohist_OpDay]). Далее напишем запрос на выборку и вставку данных с указанием всего периода в блоке WHERE.
INSERT INTO [TB44_SANDBOX].[mis].[depohist_test_query] SELECT [dh].[DEPOHIST_ID_MAJOR] ,[dh].[DEPOHIST_ID_MINOR] ,[dh].[DEPOHIST_ID_MEGA] ,[dh].[DEPOSIT_ID_MAJOR] ,[dh].[DEPOSIT_ID_MINOR] ,[dh].[DEPOSIT_ID_MEGA] ,[dh].[PERSON_ID_MAJOR] ,[dh].[PERSON_ID_MINOR] ,[dh].[PERSON_ID_MEGA] FROM [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST] AS [dh] WITH(NOLOCK) INNER JOIN [TB44_SANDBOX].[mis].[depohist_test_accounts] AS [t] WITH(NOLOCK) ON [dh].[DEPOSIT_PRINTABLENO] = [t].[account_nbr] WHERE [dh].[DEPOHIST_OpCash] < 0 AND [dh].[DEPOHIST_OpDay] >= ‘2020-01-01’ AND [dh].[DEPOHIST_OpDay] < ‘2020-03-01’
Данный запрос выполнялся около полутора минут и вставил в таблицу 1606 строк.
Теперь напишем запрос с использованием цикла WHILE.
DECLARE @startdate date = ‘2020-01-01’ DECLARE @enddate date = ‘2020-03-01’ WHILE @startdate < @enddate BEGIN INSERT INTO [TB44_SANDBOX]. [mis].[depohist_test_while] SELECT [dh].[DEPOHIST_ID_MAJOR] ,[dh].[DEPOHIST_ID_MINOR] ,[dh].[DEPOHIST_ID_MEGA] ,[dh].[DEPOSIT_ID_MAJOR] ,[dh].[DEPOSIT_ID_MINOR] ,[dh].[DEPOSIT_ID_MEGA] ,[dh].[PERSON_ID_MAJOR] ,[dh].[PERSON_ID_MINOR] ,[dh].[PERSON_ID_MEGA] FROM [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST] AS [dh] WITH(NOLOCK) INNER JOIN [TB44_SANDBOX].[mis].[depohist_test_accounts] AS [t] WITH(NOLOCK) ON [dh].[DEPOSIT_PRINTABLENO] = [t].[account_nbr] WHERE [dh].[DEPOHIST_OpCash] < 0 AND [dh].[DEPOHIST_OpDay] = @startdate SET @startdate = DATEADD(DAY, 1, @startdate) END
В начале определяем две переменные, в которых будет находится необходимый период. Далее логическое условие выполнения цикла – дата начала периода строго меньше даты окончания периода. В теле цикла между словами управления BEGIN и END наш запрос на выборку и вставку данных. Обратите внимание, что вместо периода для столбца [dh].[depohist_OpDay] мы указываем конкретное значение, которое содержит переменная @startdate. После запроса мы присваиваем нашей переменной новое значение в +1 день от текущего значения с помощью функции dateadd(), чтобы перейти на следующий шаг выполнения цикла.
Таким образом наш цикл будет выполняться пока значение переменной @startdate не станет равным значению @enddate, и на каждом шаге цикла будет выполняться запрос на выборку данных за конкретную дату.
Теперь запустим этот запрос и сравним его результаты с предыдущим.
На вкладке «Сообщения» будет несколько строк, которые соответствуют выполненному запросу на каждом шаге цикла. Запрос с использованием цикла выполнялся 35 секунд и вставил в таблицу те же 1606 строк.
Данный способ позволяет быстрее получить необходимые данные, так как при каждом выполнении будет использоваться индекс на дату, и, если в результате выполнения запроса случится какая-либо ошибка, сохранить результат ранее отработанных шагов цикла.
Цикл WHILE для выбора данных за период в T-SQL
Время прочтения: 4 мин.
Зачастую в нашей работе возникает потребность получить набор данных за определенный период.
Сделать это можно несколькими способами. В этой статье рассмотрим применение цикла WHILE для задачи поиска расходных операций за несколько месяцев по перечню счетов и сравним его с запросом, в котором весь период будет указан в блоке WHERE.Для начала разберем синтаксис конструкции WHILE. Выглядит он следующим образом:
WHILE [логическое условие] BEGIN [инструкция] END
В блоке Условие находится выражение, возвращающее значение TRUE или FALSE, в блоке Инструкций будет находиться наш запрос на выбор необходимого набора данных. Блок инструкций необходимо «ограничить» словами управления BEGIN и END.
Теперь рассмотрим на примере применение цикла WHILE и сравним его с простым запросом. Для начала создадим таблицы для перечня счетов (1000 счетов с движением средств), результатов простого запроса и результатов цикла WHILE.
CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_accounts] ( [account_nbr] nvarchar(255) ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_query] ( [DEPOHIST_ID_MAJOR] bigint ,[DEPOHIST_ID_MINOR] bigint ,[DEPOHIST_ID_MEGA] bigint ,[DEPOSIT_ID_MAJOR] bigint ,[DEPOSIT_ID_MINOR] bigint ,[DEPOSIT_ID_MEGA] bigint ,[PERSON_ID_MAJOR] bigint ,[PERSON_ID_MINOR] bigint ,[PERSON_ID_MEGA] bigint ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO CREATE TABLE [TB44_SANDBOX].[mis].[depohist_test_while] ( [DEPOHIST_ID_MAJOR] bigint ,[DEPOHIST_ID_MINOR] bigint ,[DEPOHIST_ID_MEGA] bigint ,[DEPOSIT_ID_MAJOR] bigint ,[DEPOSIT_ID_MINOR] bigint ,[DEPOSIT_ID_MEGA] bigint ,[PERSON_ID_MAJOR] bigint ,[PERSON_ID_MINOR] bigint ,[PERSON_ID_MEGA] bigint ) ON [PRIMARY] WITH (DATA_COMPRESSION = PAGE) GO
Информация об операциях в нашем случае хранится в [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST], где созданы индексы на номер счета ([DEPOSIT_PRINTABLENO]) и дату операции ([DEPOHIST_OpDay]). Далее напишем запрос на выборку и вставку данных с указанием всего периода в блоке WHERE.
INSERT INTO [TB44_SANDBOX]. [mis].[depohist_test_query] SELECT [dh].[DEPOHIST_ID_MAJOR] ,[dh].[DEPOHIST_ID_MINOR] ,[dh].[DEPOHIST_ID_MEGA] ,[dh].[DEPOSIT_ID_MAJOR] ,[dh].[DEPOSIT_ID_MINOR] ,[dh].[DEPOSIT_ID_MEGA] ,[dh].[PERSON_ID_MAJOR] ,[dh].[PERSON_ID_MINOR] ,[dh].[PERSON_ID_MEGA] FROM [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST] AS [dh] WITH(NOLOCK) INNER JOIN [TB44_SANDBOX].[mis].[depohist_test_accounts] AS [t] WITH(NOLOCK) ON [dh].[DEPOSIT_PRINTABLENO] = [t].[account_nbr] WHERE [dh].[DEPOHIST_OpCash] < 0 AND [dh].[DEPOHIST_OpDay] >= '2020-01-01' AND [dh].[DEPOHIST_OpDay] < '2020-03-01'
Данный запрос выполнялся около полутора минут и вставил в таблицу 1606 строк.
Теперь напишем запрос с использованием цикла WHILE.
DECLARE @startdate date = '2020-01-01' DECLARE @enddate date = '2020-03-01' WHILE @startdate < @enddate BEGIN INSERT INTO [TB44_SANDBOX].[mis].[depohist_test_while] SELECT [dh].[DEPOHIST_ID_MAJOR] ,[dh].[DEPOHIST_ID_MINOR] ,[dh].[DEPOHIST_ID_MEGA] ,[dh]. [DEPOSIT_ID_MAJOR] ,[dh].[DEPOSIT_ID_MINOR] ,[dh].[DEPOSIT_ID_MEGA] ,[dh].[PERSON_ID_MAJOR] ,[dh].[PERSON_ID_MINOR] ,[dh].[PERSON_ID_MEGA] FROM [BACKOFFICE_STG].[DEPOSIT].[VW_DEPOHIST] AS [dh] WITH(NOLOCK) INNER JOIN [TB44_SANDBOX].[mis].[depohist_test_accounts] AS [t] WITH(NOLOCK) ON [dh].[DEPOSIT_PRINTABLENO] = [t].[account_nbr] WHERE [dh].[DEPOHIST_OpCash] < 0 AND [dh].[DEPOHIST_OpDay] = @startdate SET @startdate = DATEADD(DAY, 1, @startdate) END
В начале определяем две переменные, в которых будет находится необходимый период. Далее логическое условие выполнения цикла – дата начала периода строго меньше даты окончания периода. В теле цикла между словами управления BEGIN и END наш запрос на выборку и вставку данных. Обратите внимание, что вместо периода для столбца [dh].[DEPOHIST_OpDay] мы указываем конкретное значение, которое содержит переменная @startdate. После запроса мы присваиваем нашей переменной новое значение в +1 день от текущего значения с помощью функции DATEADD(), чтобы перейти на следующий шаг выполнения цикла.
Таким образом наш цикл будет выполняться пока значение переменной @startdate не станет равным значению @enddate, и на каждом шаге цикла будет выполняться запрос на выборку данных за конкретную дату.
Теперь запустим этот запрос и сравним его результаты с предыдущим.
На вкладке «Сообщения» будет несколько строк, которые соответствуют выполненному запросу на каждом шаге цикла. Запрос с использованием цикла выполнялся 35 секунд и вставил в таблицу те же 1606 строк.
Данный способ позволяет быстрее получить необходимые данные, так как при каждом выполнении будет использоваться индекс на дату, и, если в результате выполнения запроса случится какая-либо ошибка, сохранить результат ранее отработанных шагов цикла.
НОУ ИНТУИТ | Лекция | Расширенное описание T-SQL
< Дополнительный материал 4 || Лекция 20: 12345678
Аннотация: Более углубленное изучение T-SQL продолжается в этой лекции. Рассматриваются новые конструкции: IF…ELSE, WHILE и CASE. Новые операторы, ранее не задействованные в примерах. Примеры и дополнительная информация, в сочетании со справочной системой SQL Server (Books Online) эффективно помогут вам разобраться во всех тонкостях нового материала.
Ключевые слова: операторы, identity, основной синтаксис, skinning, оператор DELETE, hint, junk, условия поиска, e-taxes, подзапрос, DESCRIBE, блок операторов, предупреждающее сообщение, aggregation, average, royalty, неявное преобразование типа, e-payment
Мы познакомились с этими операторами в предыдущих лекциях. Здесь также описываются ключевые слова T-SQL, используемые для управления последовательностью выполнения операторов. Вы можете использовать эти операторы и ключевые слова в любом месте, где применяется T-SQL, – в командных строках, сценариях, хранимых процедурах, в пакетных заданиях и прикладных проблемах. В частности, мы рассмотрим операторы обработки данных INSERT, UPDATE и DELETE (см. «лекцию 13» ), а также программные конструкции IF. ..ELSE, WHILE и CASE.
Прежде чем перейти к нашей основной теме, мы создадим таблицу items для использования в наших примерах. (Мы создадим эту таблицу в базе данных MyDB.) Ниже приводятся операторы T-SQL, используемые для создания таблицы items:
USE MyDB GO CREATE TABLE items ( item_category CHAR(20) NOT NULL, item_id SMALLINT NOT NULL, price SMALLMONEY NULL, item_desc VARCHAR(30) DEFAULT 'No desc' ) GO
Колонка item_id могла бы вполне подойти для свойства IDENTITY. (См. раздел «Добавление свойства IDENTITY» в «лекции 10» ). Но поскольку вы не можете явным образом помещать значения в такую колонку, то мы не используем здесь свойство IDENTITY. В данном случае мы будем использовать более гибкий подход в примерах, где используется оператор INSERT.
Оператор INSERT
Оператор INSERT, введенный в «лекции 13» , используется для добавления новой строки или строк в таблицу или представление. Ниже показан основной синтаксис для оператора INSERT:
INSERT [INTO] имя_таблицы [(список_колонок)] VALUES выражение | производная_таблица
Ключевое слово INTO и параметр список_колонок не являются обязательными. Параметр список_колонок указывает, в какие колонки вы помещаете данные; эти значения имеют взаимно-однозначное соответствие (по порядку) со значениями, указанными в выражении (которое может быть просто списком значений). Рассмотрим некоторые примеры.
Вставка строк
В следующем примере показано, как вставить одну строку данных в таблицу items:
INSERT INTO items (item_category, item_id, price, item_desc) VALUES ('health food', 1, 4.00, 'tofu 6 oz.') GO
Поскольку мы задали значения для каждой колонки данной таблицы и перечислили эти значения в порядке соответствующих колонок таблицы, то можно было бы совсем не использовать параметр список_колонок. Но если бы значения были заданы не в порядке колонок, то вы получили бы неверные данные или появилось бы сообщение об ошибке. Например, если запустить следующую последовательность операторов, то вы получите сообщение об ошибке, указанное после этой последовательности:
INSERT INTO items VALUES (1, 'health food', 4.00, 'tofu 6 oz.') GO Server: Msg 245, Level 16, State 1, Line 1 Syntax error converting the varchar value 'health food' to a column of data type smallint. (Синтаксическая ошибка в результате преобразования varchar-значения 'health food' в колонке данных типа smallint)
Невыполнение вставки строки и это сообщение являются следствием неверного порядка значений Мы пытались поместить значение item_id в колонку item_category и значение item_category в колонку item_id. Указанные значения несовместимы с типами данных для этих колонок. Если бы они были совместимы, то SQL Server позволил бы вставить данную строку независимо от порядка следования значений.
Чтобы увидеть, как выглядит строка, которую мы вставили в таблицу, укажите запрос выбора всех строк таблицы с помощью следующего оператора SELECT:
SELECT * from items GO Вы получите следующий набор результатов: item_category item_id price item_desc ------------------------------------------------------- health food 1 4.0000 tofu 6 oz.
При создании таблицы items было определено, что колонка price (цена) может содержать пустые значения, а для колонки item_desc (описание) было задано значение по умолчанию No desc. (Нет описания). Если в операторе INSERT не указано никакого значения для колонки price, то в эту колонку для новой строки будет помещено значение NULL. Если не указано никакого значения для колонки item_desc, то в эту колонку для новой строки будет помещено значение No desc.
Дальше >>
< Дополнительный материал 4 || Лекция 20: 12345678
Как организовать цикл в sql
SQL — Урок 18.
Хранимые процедуры. Часть 4.Сегодня узнаем, как работать с циклами, т.е. выполнять один и тот же запрос несколько раз. В MySQL для работы с циклами применяются операторы WHILE , REPEAT и LOOP .
Оператор цикла WHILE
Запрос будет выполняться до тех пор, пока условие истинно. Давайте посмотрим на примере, как это работает. Предположим, мы хотим знать названия, авторов и количество книг, которые поступили в различные поставки. Интересующая нас информация хранится в двух таблицах — Журнал Поставок (magazine_incoming) и Товар (products). Давайте напишим интересующий нас запрос:
А что, если нам необходимо, чтобы результат выводился не в одной таблице, а по каждой поставке отдельно? Конечно, можно написать 3 разных запроса, добавив в каждый еще одно условие:
Т.е. мы ввели переменную i, по умолчанию равную 3, сервер выполнит запрос с id поставки равным 3, затем уменьшит i на единицу (SET i=i-1), убедится, что новое значение переменной i положительно (i>0) и снова выполнит запрос, но уже с новым значением id поставки равным 2. Так будет происходить, пока переменная i не получит значение 0, условие станет ложным, и цикл закончит свою работу.
Чтобы убедиться в работоспособности цикла создадим хранимую процедуру books и поместим в нее цикл:
Теперь вызовем процедуру:
Теперь у нас 3 отдельные таблицы (по каждой поставке). Согласитесь, что код с циклом гораздо короче трех отдельных запросов. Но в нашей процедуре есть одно неудобство, мы объявили количество выводимых таблиц значением по умолчанию (DEFAULT 3), и нам придется с каждой новой поставкой менять это значение, а значит код процедуры. Гораздо удобнее сделать это число входным параметром. Давайте перепишем нашу процедуру, добавив входной параметр num, и, учитывая, что он не должен быть равен 0:
Убедитесь, что с другими параметрами, мы по-прежнему получаем таблицы по каждой поставке. У нашего цикла есть еще один недостаток — если случайно задать слишком большое входное значение, то мы получим псевдобесконечный цикл, который загрузит сервер бесполезной работой. Такие ситуации предотвращаются с помощью снабжения цикла меткой и использования оператора LEAVE , обозначающего досрочный выход из цикла.
Итак, мы снабдили наш цикл меткой wet вначале (wet:) и в конце, а также добавили еще одно условие — если входной параметр больше 10 (число 10 взято произвольно), то цикл с меткой wet следует закончить (IF (i>10) THEN LEAVE wet). Таким образом, если мы случайно вызовем процедуру с большим значением num, наш цикл прервется после 10 итераций (итерация — один проход цикла).
Циклы в MySQL, так же как и операторы ветвления, на практике в web-приложениях почти не используются. Поэтому для двух других видов циклов приведем лишь синтаксис и отличия. Вряд ли вам доведется их использовать, но знать об их существовании все-таки надо.
Оператор цикла REPEAT
Условие цикла проверяется не в начале, как в цикле WHILE, а в конце, т.е. хотя бы один раз, но цикл выполняется. Сам же цикл выполняется, пока условие ложно. Синтаксис следующий:
Оператор цикла LOOP
Этот цикл вообще не имеет условий, поэтому обязательно должен иметь оператор LEAVE. Синтаксис следующий:
На этом мы заканчиваем уроки посвященные SQL. Конечно, мы рассмотрели не все возможности этого языка запросов, но в реальной жизни вам вряд ли придется столкнуться даже с тем, что вы уже знаете.
Напомню, на реальных сайтах, вы обычно вводите информацию в какие-нибудь html-формы, затем сценарий на каком-либо языке (php, java. ) извлекает эти данные из формы и заносит их в БД. При необходимости происходит обратный процесс, т.е. данные извлекаются из БД и выводятся на страницы сайта. Оба процесса происходят посредством SQL-запросов. HTML вы знаете, с базами данных разобрались, SQL-запросы писать научились, осталось изучить PHP, чтобы ваши сайты превратились в полноправные web-приложения. Это и есть ваш следующий шаг. До встречи в уроках PHP.
Видеоуроки php + mysql
Если этот сайт оказался вам полезен, пожалуйста, посмотрите другие наши статьи и разделы.
Использование циклов T-SQL для выделенных пулов SQL в Azure Synapse Analytics
В эту статью включены советы по разработке решений для выделенного пула SQL с помощью циклов T-SQL и замены курсоров.
Назначение циклов WHILE
Выделенные пулы SQL в Azure Synapse поддерживают цикл WHILE для многократного выполнения блоков операторов. Цикл WHILE продолжается, пока не будут выполнены указанные условия или пока код не прервет цикл с помощью ключевого слова BREAK.
Циклы полезны для замены курсоров, определенных в коде SQL. К счастью, почти все курсоры, записанные в коде SQL, относятся к разряду перемотки и доступности только для чтения. Таким образом, циклы WHILE — отличная альтернатива для замены курсоров.
Замена курсоров в выделенном пуле SQL
Прежде чем обращаться к циклам, задайте себе следующий вопрос: «Можно ли переписать этот курсор, задействовав операции, ориентированные на работу с наборами данных?»
Во многих случаях ответ будет утвердительным, и это может оказаться лучшим вариантом. Операция, ориентированная на работу с набором данных, нередко выполняется быстрее, чем итеративный метод построчного перебора.
Курсоры быстрой перемотки, доступные только для чтения, легко заменяются циклической конструкцией. Следующий пример является простым. Приведенный в примере код обновляет статистику для каждой таблицы в базе данных. Перебор таблиц в цикле позволяет выполнить каждую команду в последовательности.
Для начала создайте временную таблицу с уникальным номером строки, обозначающим отдельные операторы:
Как выполнить цикл в хранимой процедуре MySQL
База данных
Конструкция цикла в SQL и основных языках программирования относится к конструкции, которая многократно выполняет инструкции при условии, что указанное условие истинно. Набор инструкций, выполняемых внутри цикла, может быть одним запросом или набором команд, ведущих к большему набору запросов.
В этом руководстве мы обсудим, как реализовать цикл MySQL внутри процедуры.
В этом руководстве мы предполагаем, что вы знаете, как работать с процедурами MySQL.
Особенности MySQL Loop
Прежде чем мы углубимся в «как» реализации цикла MySQL, давайте перечислим несколько функций цикла:
- Цикл может содержать более одного оператора, каждый из которых заканчивается точкой с запятой.
- Все операторы и значения внутри цикла выполняются постоянно, но только если установленное условие истинно.
- Вы можете завершить цикл, используя инструкцию LEAVE.
- MySQL позволяет вам дать имя цикла, используя синтаксис loopName: LOOP
Основное использование
Общий синтаксис для реализации простого цикла MySQL:
[ begin_label: ] LOOP
statement_list
END LOOP [ end_label ]
Список операторов должен также включать условие LEAVE, которое указывает, когда цикл должен завершиться.
Этикетка представляет имя цикла.
Синтаксис ниже показывает реализацию цикла с оператором LEAVE:
[ name ] : LOOP
statement_list ;
IF condition THEN
LEAVE [ label ] ;
END IF ;
END LOOP [ end_label ] ;
Пример использования
В этом разделе я попытаюсь проиллюстрировать, как использовать LOOP в процедуре. Цель процедуры — реализовать простой цикл и не будет отражать реальные данные.
Рассмотрим процедуру ниже, которая реализует цикл для поиска четных чисел:
DROP PROCEDURE IF EXISTS loopMe ;
DELIMITER $$
CREATE PROCEDURE loopMe ( )
BEGIN
DECLARE i INT ;
SET i = 1 ;
SET @str = » ;
iterateMe: LOOP
IF i > 10 THEN
LEAVE iterateMe ;
END IF ;
SET i = i + 1 ;
IF ( i mod 2 ) THEN
ITERATE iterateMe ;
ELSE
SET @str = CONCAT ( @str , i , ‘ ‘ ) ;
END IF ;
END LOOP ;
SELECT @str AS EVEN ;
END $$
DELIMITER ;
CALL loopMe ( )
После вызова цикла мы получаем значения четных чисел, разделенных пробелами, как указано в функции CONCAT ().
Заключение
В этом руководстве мы рассмотрели основы использования цикла MySQL для итерации набора инструкций. Циклы MySQL работают аналогично циклам в других языках программирования, таких как Python, C ++ и JavaScript.
Выполнить цикл while в SQL Server 2008
Выполнить цикл while в SQL Server 2008Есть ли какой-либо метод для реализации do while
цикла в SQL Server 2008?
sql-server sql-server-2008 loops while-loop do-while
—
Нитеш Нараянан
источник
Ответы:
Я не уверен насчет DO-WHILE в MS SQL Server 2008, но вы можете изменить логику цикла WHILE, чтобы ИСПОЛЬЗОВАТЬ как цикл DO-WHILE.
Примеры взяты отсюда: http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of- while-loop-with-continue-and-break-keywords/
Пример цикла WHILE
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 END GOResultSet:
1 2 3 4 5Пример цикла WHILE с ключевым словом BREAK
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 IF @intFlag = 4 BREAK; END GOResultSet:
1 2 3Пример цикла WHILE с ключевыми словами CONTINUE и BREAK
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 CONTINUE; IF @intFlag = 4 -- This will never executed BREAK; END GOResultSet:
1 2 3 4 5
Но старайтесь избегать петель на уровне базы данных. Ссылка .
—
Pratik
источник
Если вас не очень обидело GOTO
ключевое слово, его можно использовать для имитации в DO
/ WHILE
в T-SQL. Рассмотрим следующий довольно бессмысленный пример, написанный псевдокодом:
SET I=1 DO PRINT I SET I=I+1 WHILE I<=10
Вот эквивалентный код T-SQL с использованием goto:
DECLARE @I INT=1; START: -- DO PRINT @I; SET @I+=1; IF @I<=10 GOTO START; -- WHILE @I<=10
Обратите внимание на соответствие между GOTO
включенным решением и исходным DO
/ WHILE
псевдокодом. Аналогичная реализация с использованием WHILE
цикла будет выглядеть так:
DECLARE @I INT=1; WHILE (1=1) -- DO BEGIN PRINT @I; SET @I+=1; IF NOT (@I<=10) BREAK; -- WHILE @I<=10 END
Теперь вы, конечно, можете переписать этот конкретный пример как простой WHILE
цикл, так как это не такой уж хороший кандидат для конструкции DO
/ WHILE
. Акцент был сделан на краткости примера, а не на применимости, поскольку законные случаи, требующие DO
/ WHILE
, редки.
REPEAT / UNTIL, кто-нибудь (НЕ работает в T-SQL)?
SET I=1 REPEAT PRINT I SET I=I+1 UNTIL I>10
… и GOTO
решение на основе T-SQL:
DECLARE @I INT=1; START: -- REPEAT PRINT @I; SET @I+=1; IF NOT(@I>10) GOTO START; -- UNTIL @I>10
Благодаря творческому использованию GOTO
и логической инверсии с помощью NOT
ключевого слова существует очень тесная связь между исходным псевдокодом и GOTO
основанным на нем решением. Аналогичное решение с использованием WHILE
цикла выглядит так:
DECLARE @I INT=1; WHILE (1=1) -- REPEAT BEGIN PRINT @I; SET @I+=1; IF @I>10 BREAK; -- UNTIL @I>10 END
Можно привести аргумент, что для случая REPEAT
/ решение UNTIL
на WHILE
основе проще, потому что условие if не инвертируется. С другой стороны, он более подробный.
Если бы не все пренебрежение к использованию GOTO
, это могло бы быть даже идиоматическим решением для тех немногих случаев, когда эти конкретные (злые) конструкции цикла необходимы в коде T-SQL для ясности.
Используйте их по своему усмотрению, стараясь не страдать от гнева своих товарищей-разработчиков, когда они поймают вас на использовании того, что так оскорбительно GOTO
.
—
Михаил Гольдштейн
источник
Кажется, я припоминаю, что читал эту статью не один раз, и ответ близок только к тому, что мне нужно.
Обычно, когда я думаю, что мне понадобится DO WHILE
T-SQL, это потому, что я повторяю курсор и ищу в основном оптимальную ясность (а не оптимальную скорость). В T-SQL это похоже на WHILE TRUE
/ IF BREAK
.
Если именно такой сценарий привел вас сюда, этот фрагмент может сэкономить вам время. В противном случае, добро пожаловать, я. Теперь я могу быть уверен, что был здесь не раз. 🙂
DECLARE Id INT, @Title VARCHAR(50) DECLARE Iterator CURSOR FORWARD_ONLY FOR SELECT Id, Title FROM dbo.SourceTable OPEN Iterator WHILE 1=1 BEGIN FETCH NEXT FROM @InputTable INTO @Id, @Title IF @@FETCH_STATUS < 0 BREAK PRINT 'Do something with ' + @Title END CLOSE Iterator DEALLOCATE Iterator
К сожалению, кажется, что T-SQL не предлагает более чистого способа одиночного определения операции цикла, чем этот бесконечный цикл.
—
Shannon
источник
Вы также можете использовать переменную выхода, если хотите, чтобы ваш код был более читабельным:
DECLARE @Flag int = 0 DECLARE @Done bit = 0 WHILE @Done = 0 BEGIN SET @Flag = @Flag + 1 PRINT @Flag IF @Flag >= 5 SET @Done = 1 END
Это, вероятно, будет более уместно, если у вас более сложный цикл и вы пытаетесь отслеживать логику. Как указано, циклы дороги, поэтому попробуйте использовать другие методы, если можете.
—
Sebris87
источник
Только цикл пока официально поддерживается SQL-сервером. Уже есть ответ на цикл DO while. Я подробно рассказываю о способах достижения различных типов циклов на SQL-сервере.
Если вы знаете, что вам все равно нужно завершить первую итерацию цикла, вы можете попробовать версию SQL-сервера DO..WHILE или REPEAT..UNTIL .
DO..WHILE цикл
DECLARE @X INT=1; WAY: --> Here the DO statement PRINT @X; SET @X += 1; IF @X<=10 GOTO WAY;
REPEAT..UNTIL Цикл
DECLARE @X INT = 1; WAY: -- Here the REPEAT statement PRINT @X; SET @X += 1; IFNOT(@X > 10) GOTO WAY;
Цикл FOR
DECLARE @cnt INT = 0; WHILE @cnt < 10 BEGIN PRINT 'Inside FOR LOOP'; SET @cnt = @cnt + 1; END; PRINT 'Done FOR LOOP';
Ссылка
—
Сомнатх Мулук
источник
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.
Использование курсоров и циклов в Transact-SQL | Info-Comp.ru
Сегодня будем рассматривать очень много чего интересного, например как запустить уже созданную процедуру, которая принимает параметры, массово, т.е. не только со статическим параметрами, а с параметрами, которые будут меняться, например, на основе какой-нибудь таблицы, как обычная функция, и в этом нам помогут как раз курсоры и циклы, и как это все реализовать сейчас будем смотреть.
Как Вы поняли, курсоры и циклы мы будем рассматривать применимо к конкретной задачи. А какой задачи, сейчас расскажу.
Существует процедура, которая выполняет какие-то действия, которые не может выполнить обычная функция SQL например, расчеты и insert на основе этих расчетов. И Вы ее запускаете, например вот так:
EXEC test_PROCEDURE par1, par2
Другими словами Вы запускаете ее только с теми параметрами, которые были указаны, но если Вам необходимо запустить данную процедуру скажем 100, 200 или еще более раз, то согласитесь это не очень удобно, т. е. долго. Было бы намного проще, если бы мы взяли и запускали процедуру как обычную функцию в запросе select, например:
SELECT my_fun(id) FROM test_table
Другими словами функция отработает на каждую запись таблицы test_table, но как Вы знаете процедуру так использовать нельзя. Но существует способ, который поможет нам осуществить задуманное, точнее даже два способа первый это с использованием курсора и цикла и второй это просто с использованием цикла, но уже без курсора. Оба варианта подразумевают, что мы будем создавать дополнительную процедуру, которую в дальнейшем мы будем запускать.
Примечание! Все примеры будем писать в СУБД MS SQL Server 2008, используя Management Studio. Также все нижеперечисленные действия требуют определённых знаний языка SQL, а точнее Transact-SQL. Начинающим могу посоветовать посмотреть мой видеокурс по T-SQL, на котором рассматриваются все базовые конструкции.
И так приступим, и перед тем как писать процедуру, давайте рассмотрим исходные данные нашего примера.
Допустим, есть таблица test_table
CREATE TABLE [dbo].[test_table]( [number] [numeric](18, 0) NULL, [pole1] [varchar](50) NULL, [pole2] [varchar](50) NULL ) ON [PRIMARY] GO
В нее необходимо вставлять данные, на основе каких-то расчетов, которые будет выполнять процедура my_proc_test, в данном случае она просто вставляет данные, но на практике Вы можете использовать свою процедуру, которая может выполнять много расчетов, поэтому в нашем случае именно эта процедура не важна, она всего лишь для примера. Ну, давайте создадим ее:
CREATE PROCEDURE [dbo].[my_proc_test] (@number numeric, @pole1 varchar(50), @pole2 varchar(50)) AS BEGIN INSERT INTO dbo.test_table (number, pole1, pole2) VALUES (@number, @pole1, @pole2) END GO
Она просто принимает три параметра и вставляет их в таблицу.
И допустим эту процедуру, нам нужно запустить столько раз, сколько строк в какой-нибудь таблице или представлении (VIEWS) , другими словами запустить ее массово для каждой строки источника.
И для примера создадим такой источник, у нас это будет простая таблица test_table_vrem, а у Вас это может быть, как я уже сказал свой источник, например временная таблица или представление:
CREATE TABLE [dbo].[test_table_vrem]( [number] [numeric](18, 0) NULL, [pole1] [varchar](50) NULL, [pole2] [varchar](50) NULL ) ON [PRIMARY] GO
Заполним ее тестовыми данными:
И теперь нашу процедуру необходимо запустить для каждой строки, т.е. три раза с разными параметрами. Как Вы понимаете значения этих полей и есть наши параметры, другими словами, если бы мы запускали нашу процедуру вручную, это выглядело вот так:
exec my_proc_test 1, ‘pole1_str1’, ‘pole2_str1’
И так еще три раза, с соответствующими параметрами.
Но нам так не охота, поэтому мы напишем еще одну дополнительную процедуру, которая и будет запускать нашу основную процедуру столько раз, сколько нам нужно.
Первый вариант.
Используем курсор и цикл в процедуре
Перейдем сразу к делу и напишем процедуру (my_proc_test_all), код я как всегда прокомментировал:
CREATE PROCEDURE [dbo].[my_proc_test_all] AS --объявляем переменные DECLARE @number bigint DECLARE @pole1 varchar(50) DECLARE @pole2 varchar(50) --объявляем курсор DECLARE my_cur CURSOR FOR SELECT number, pole1, pole2 FROM test_table_vrem --открываем курсор OPEN my_cur --считываем данные первой строки в наши переменные FETCH NEXT FROM my_cur INTO @number, @pole1, @pole2 --если данные в курсоре есть, то заходим в цикл --и крутимся там до тех пор, пока не закончатся строки в курсоре WHILE @@FETCH_STATUS = 0 BEGIN --на каждую итерацию цикла запускаем нашу основную процедуру с нужными параметрами exec dbo. my_proc_test @number, @pole1, @pole2 --считываем следующую строку курсора FETCH NEXT FROM my_cur INTO @number, @pole1, @pole2 END --закрываем курсор CLOSE my_cur DEALLOCATE my_cur GO
И теперь осталось нам ее вызвать и проверить результат:
Код:
--до выполнения процедуры SELECT * FROM test_table --вызов процедуры EXEC dbo.my_proc_test_all --после выполнения процедуры SELECT * FROM test_table
Как видите, все у нас отработало как надо, другими словами процедура my_proc_test сработала все три раза, а мы всего лишь один раз запустили дополнительную процедуру.
Второй вариант.
Используем только цикл в процедуре
Сразу скажу, что здесь требуется нумерация строк во временной таблице, т.е. каждая строка должна быть пронумерована, например 1, 2, 3 таким полем у нас во временной таблице служит number.
Пишем процедуру my_proc_test_all_v2
CREATE PROCEDURE [dbo].[my_proc_test_all_v2] AS --объявляем переменные DECLARE @number bigint DECLARE @pole1 varchar(50) DECLARE @pole2 varchar(50) DECLARE @cnt int DECLARE @i int --узнаем количество строк во временной таблице SELECT @cnt=count(*) FROM test_table_vrem --задаем начальное значение идентификатора SET @i=1 WHILE @cnt >= @i BEGIN --присваиваем значения нашим параметрам SELECT @number=number, @pole1= pole1, @pole2=pole2 FROM test_table_vrem WHERE number = @I --на каждую итерацию цикла запускаем нашу основную процедуру с нужными параметрами EXEC dbo.my_proc_test @number, @pole1, @pole2 --увеличиваем шаг set @i= @i+1 END GO
И проверяем результат, но для начала очистим нашу таблицу, так как мы же ее только что уже заполнили по средствам процедуры my_proc_test_all:
--очистим таблицу DELETE test_table --до выполнения процедуры SELECT * FROM test_table --вызов процедуры EXEC dbo. my_proc_test_all_v2 --после выполнения процедуры SELECT * FROM test_table
Как и ожидалось результат такой же, но уже без использования курсоров. Какой вариант использовать решать Вам, первый вариант хорош, тем, что в принципе не нужна нумерация, но как Вы знаете, курсоры работают достаточно долго, если строк в курсоре будет много, а второй вариант хорош тем, что отработает, как мне кажется быстрей, опять же таки, если строк будет много, но нужна нумерация, лично мне нравится вариант с курсором, а вообще решать Вам может Вы сами придумаете что-то более удобное, я всего лишь показал основы того, как можно реализовать поставленную задачу. Удачи!
Заметка! Если Вас интересует SQL и T-SQL, рекомендую посмотреть мои видеокурсы по T-SQL, с помощью которых Вы «с нуля» научитесь работать с SQL и программировать с использованием языка T-SQL в Microsoft SQL Server.
Цикл SQL WHILE с простыми примерами
Цикл SQL WHILE дает нам преимущество многократного выполнения операторов SQL до тех пор, пока указанный результат условия не окажется ложным.
В следующих разделах этой статьи мы будем использовать больше блок-схем, чтобы объяснить понятия и примеры. По этой причине, во-первых, мы кратко объясним, что такое блок-схема. Блок-схема — это наглядный геометрический символ, помогающий наглядно объяснить алгоритмы. Блок-схема используется для простого проектирования и документирования алгоритмов. На блок-схеме каждый геометрический символ имеет разные значения.
Следующая блок-схема объясняет основную структуру цикла WHILE в SQL:
Как видите, в каждой итерации цикла проверяется заданное условие, а затем по результату условия определяется поток кода. Если результат условия истинен, оператор SQL будет выполнен. В противном случае поток кода выйдет из цикла. Если какой-либо оператор SQL существует вне цикла, он будет выполнен.
Синтаксис и пример цикла SQL WHILE
Синтаксис цикла WHILE в SQL выглядит следующим образом:
WHILE условие НАЧАЛО {. ..операторы…} КОНЕЦ |
После этих объяснений мы приведем очень простой пример цикла WHILE в SQL. В приведенном ниже примере пример цикла WHILE запишет значение переменной десять раз, после чего цикл завершится:
1 2 3 4 5 6 7 | DECLARE @Counter INT SET @Counter=1 WHILE ( @Counter <= 10) BEGIN PRINT ‘Значение счетчика = ‘ + CONVERT(VARCHAR,@SET3) @Counter + 1КОНЕЦ |
Теперь мы обработаем пример цикла WHILE построчно и детально изучим его.
В этой части кода мы объявляем переменную и присваиваем ей инициализирующее значение:
DECLARE @Counter INT SET @Counter=1 |
Эта часть кода имеет указанное условие, что пока значение переменной не достигнет 10, цикл продолжается и выполняет оператор PRINT. В противном случае условие while не сработает и цикл завершится:
ПОКА ( @Counter <= 10) |
В этой последней части кода мы выполнили оператор SQL, а затем увеличили значение переменной:
BEGIN PRINT ‘Значение счетчика = ‘ + CONVERT(VARCHAR,@Counter) SET @Counter = @Counter + 1 END |
Следующая блок-схема наглядно иллюстрирует этот пример цикла WHILE:
Бесконечный цикл SQL WHILE
В бесконечном цикле, также известном как бесконечный цикл, результат условия никогда не будет ложным, поэтому цикл никогда не заканчивается и может работать вечно. Представьте, что у нас есть цикл WHILE, и мы не увеличиваем значение переменной. В этом случае цикл выполняется бесконечно и никогда не заканчивается. Теперь мы реализуем этот сценарий с помощью следующего примера. Нам нужно учесть одну вещь, что мы не должны забывать отменять выполнение запроса вручную:
1 2 3 4 5 6 7 | DECLARE @Counter INT SET @Counter=1 WHILE ( @Counter <= 10) BEGIN PRINT ‘Кто-нибудь меня остановит!’
КОНЕЦ |
На следующей блок-схеме очевидно, что значение переменной никогда не меняется; поэтому цикл никогда не заканчивается. Причина этой проблемы в том, что переменная всегда равна 1, поэтому условие возвращает true для каждой итерации цикла:
Оператор BREAK
Оператор BREAK используется в цикле SQL WHILE для немедленного выхода из текущей итерации цикла при возникновении определенных условий. Обычно оператор IF…ELSE используется для проверки того, произошло ли условие или нет. Дополнительные сведения об операторе IF…ELSE см. во вводной и обзорной статье инструкции SQL IF.
В следующем примере показано использование оператора BREAK в цикле WHILE:
1 2 3 4 5 6 7 8 10 11 | DECLARE @Counter INT SET @Counter=1 WHILE ( @Counter <= 10) BEGIN PRINT ‘Значение счетчика = ‘ > CONVERT(VARCHAR,@Counter) 3 =7НАЧАЛО РАЗРЫВ КОНЕЦ SET @Counter = @Counter + 1 END |
В этом примере мы проверили значение переменной, и когда значение равно или больше 7, код вошел в блок IF…ELSE и выполнил оператор BREAK, поэтому он немедленно вышел из цикла. По этой причине в сообщении отображаются значения переменной до 7. Если условие оператора IF…ELSE не выполняется, цикл будет выполняться до тех пор, пока результат условия не станет ложным. Следующая блок-схема наглядно объясняет рабочую логику примера оператора BREAK:
Оператор ПРОДОЛЖИТЬ
Оператор CONTINUE используется в цикле SQL WHILE, чтобы остановить текущую итерацию цикла при возникновении определенных условий, а затем начать новую итерацию с начала цикла. Предположим, что мы хотим записать в цикле WHILE только четные числа. Чтобы решить эту проблему, мы можем использовать оператор CONTINUE . В следующем примере мы проверим, является ли значение переменной нечетным или четным. Если значение переменной нечетное, код входит в блоки операторов IF…ELSE и увеличивает значение переменной, выполняя CONTINUE и начинает новую итерацию:
1 2 3 4 5 6 7 8 10 11 0003 12 13 . | DECLARE @Counter INT SET @Counter=1 WHILE ( @Counter <= 20) BEGIN
IF @Counter % 2 =1 3 9 0003SET @Counter = @Counter+ 1 Продолжить END ПЕЧАТЬ ‘ЗА ЗАДЕЛЕНИЕ ОПЕРЬЕТ =’+ преобразовать (varchar, @счетчик) Установить @Counter = @Counter+ 1 END |
Следующая блок-схема наглядно объясняет рабочую логику примера оператора CONTINUE:
Чтение записей таблицы через цикл WHILE
В следующем примере мы будем читать данные таблицы построчно. Сначала мы создадим пример таблицы:
1 2 3 4 5 6 7 8 10 110003 12 13 14 1993 16000313 14 9000.9000 313 14 9000 3 | ИСПОЛЬЗОВАТЬ tempdb GO УДАЛИТЬ ТАБЛИЦУ, ЕСЛИ СУЩЕСТВУЕТ SampleTable CREATE TABLE SampleTable (Id INT, CountryName NVARCHAR(100), ReadStatus TINYINT) GO INSERT INTO SampleTable (Id, CountryName, ReadStatus) Значения (1, 3 90 0, 0, 0, Германия (2, ‘Франция’, 0), (3, ‘Италия’, 0), (4, ‘Нидерланды’, 0) , (5, ‘Польша’, 0) 32 32 |
На этом шаге мы будем читать все данные построчно с помощью цикла WHILE:
1 2 3 4 5 6 7 8 10 110003 12 13 14 1999009 9000 214 9000 3 9000 3 9000 3 9000 2 9000 214 9000 3 9000 3 9000 214 9000 3 9000 2 | USE tempdb GO
DECLARE @Counter INT , @MaxId INT, @CountryName NVARCHAR(100) SELECT @Counter = min(Id) , @MaxId = max(Id) FROMULL SampleTable NISLE 0 NOT(@3Counter 0 NOT(@3Counter 0И @Counter <= @MaxId) BEGIN SELECT @CountryName = CountryName FROM SampleTable WHERE Id = @Counter
90PR002 90PR002 90PR002 90PR002 название страны ‘ + @CountryName SET @Counter = @Counter + 1 КОНЕЦ |
В этом примере мы читаем строки таблицы через цикл WHILE. Мы также можем разрабатывать более сложные и продвинутые циклы в зависимости от наших потребностей.
Заключение
В этой статье мы изучили цикл SQL WHILE на довольно простых примерах. Мы также виртуализировали и объяснили примеры блок-схемами. Цикл WHILE помогает нам выполнять итерационные операции в SQL Server. В то же время операторы BREAK и CONTINUE можно использовать для управления итерацией цикла WHILE в SQL Server.
- Автор
- Последние сообщения
Esat Erkec
Esat Erkec — специалист по SQL Server, который начал свою карьеру более 8 лет назад в качестве разработчика программного обеспечения. Он является сертифицированным экспертом по решениям Microsoft для SQL Server.
Большая часть его карьеры была посвящена администрированию и разработке баз данных SQL Server. Его текущие интересы связаны с администрированием баз данных и бизнес-аналитикой. Вы можете найти его в LinkedIn.
Просмотреть все сообщения от Esat Erkec
Последние сообщения от Esat Erkec (посмотреть все)
Понимание циклов While в SQL Server
Цикл SQL While используется для многократного выполнения определенного фрагмента сценария SQL.
В этой статье рассматриваются некоторые основные функции цикла SQL While в Microsoft SQL Server с помощью примеров.
SQL Синтаксис цикла while
Синтаксис цикла SQL While следующий:
WHILE условие BEGIN //Выражения SQL END; |
Цикл while в SQL начинается с ключевого слова WHILE, за которым следует условие, которое возвращает логическое значение, т.е. Правда или ложь.
Тело цикла while продолжает выполняться, пока условие не вернет false. Тело цикла while в SQL начинается с блока BEGIN и заканчивается блоком END.
Простой пример: вывод чисел с помощью SQL цикла While
Давайте начнем с очень простого примера, в котором мы используем цикл while SQL для вывода первых пяти положительных целых чисел. ценности:
1 2 3 4 5 6 7 8 | DECLARE @count INT; УСТАНОВИТЬ @count = 1;
WHILE @count<= 5 НАЧАЛО PRINT @count SET @count = @count + 1; КОНЕЦ; |
В приведенном выше скрипте мы сначала объявляем переменную целочисленного типа @count и устанавливаем ее значение равным 5.
Затем мы выполняем цикл While, который проверяет, меньше или равно ли значение переменной @count 5. Если Переменная @count имеет значение меньше или равное 5, выполняется тело цикла и текущее значение Переменная @count выводится на консоль.
В следующей строке значение переменной @count увеличивается на 1. Цикл While продолжает выполняться до тех пор, пока значение переменной @count не станет больше 5. Вот результат:
Вставка записей с помощью цикла SQL While
Давайте теперь посмотрим, как используется цикл SQL While для вставки фиктивных записей в таблицу базы данных.
Для этого нам понадобится простая база данных «CarShop»:
СОЗДАНИЕ БАЗЫ ДАННЫХ CarShop |
Мы создадим одну таблицу, т.е. автомобили в базе данных CarShop. Таблица Cars будет состоять из трех столбцов: Id, Name и Цена. Выполните следующий скрипт:
1 2 3 4 5 6 7 | ИСПОЛЬЗОВАТЬ CarShop СОЗДАТЬ ТАБЛИЦУ Автомобили ( Id INT PRIMARY KEY IDENTITY(1,1), Name VARCHAR (50) NOT NULL, Price INT ) |
Давайте теперь воспользуемся циклом While в SQL, чтобы вставить 10 записей в таблицу Cars. Выполните следующий скрипт:
1 2 3 4 5 6 7 8 | DECLARE @count INT; УСТАНОВИТЬ @count = 1;
WHILE @count<= 10 BEGIN INSERT INTO Cars VALUES(‘Car-‘+CAST(@count as varchar), @count*100) SET @count = @count + КОНЕЦ; |
В приведенном выше сценарии мы снова объявляем переменную @count и инициализируем ее значением 1. Далее выполняется цикл while, пока значение переменной @count не станет больше 10, что означает, что цикл while выполняется 10 раз.
В теле цикла while запрос INSERT используется для вставки одной записи в таблицу Cars. Для столбца Name к значению переменной @count добавляется строка Car-
. Для столбца «Цена» таблицы «Автомобили»
значение переменной @count умножается на 100.
Теперь, если вы выберете все записи из таблицы Cars с запросом «SELECT * FROM Cars», вы должны увидеть следующий вывод:
Реализация пейджинга с помощью цикла SQL While
Цикл while также можно использовать для реализации пейджинга. Пейджинг относится к отображению подмножества записей из таблицы данных в любой конкретный момент времени.
В следующем скрипте цикл while будет использоваться для одновременного выбора двух записей из таблицы Cars. выбранные записи затем отображаются в выводе консоли:
1 2 3 4 5 6 7 8 9 10 11 12 13 | DECLARE @count INT DECLARE @limit INT; SET @count = 0 SET @limit = 2;
WHILE @count< 10 BEGIN SELECT * FROM Cars ORDER BY Id OFFSET @count ROWS ROWS0002 ВЫБЕРИТЕ СЛЕДУЮЩИЕ @limit ТОЛЬКО СТРОКSET @count = @count + 2; КОНЕЦ; |
В приведенном выше сценарии мы инициализируем две переменные, то есть @count и @limit. Начальные значения для @count и Переменные @limit равны 0 и 2 соответственно. Цикл while выполняется, пока остается значение переменной @count менее 10.
Внутри цикла while используется предложение OFFSET, чтобы пропустить первые N строк таблицы Cars. Предложение FETCH NEXT выбирает следующие N записей.
В первой итерации значение OFFSET будет равно 0, поскольку @count равно 0, будут отображаться первые две записи. В на второй итерации, поскольку переменная @count будет иметь значение 2, первые две записи будут пропущены, а будут восстановлены записи 3 и 4.
Таким образом, все записи из таблицы Cars будут получены наборами по два. Результат выглядит следующим образом:
В выводе вы можете увидеть все записи из таблицы Cars, напечатанные по две на консоли.
Операторы CONTINUE и BREAK
Оператор CONTINUE используется для возврата управления к началу цикла while в SQL. Оператор BREAK используется для завершения цикла.
В следующем сценарии показано, как использовать оператор CONTINUE внутри цикла while для вывода первых пяти положительных значений. четные целые числа:
1 2 3 4 5 6 7 8 9 10 11 12 13 10 309002 1500003 3 | DECLARE @count INT; DECLARE @mod INT; УСТАНОВИТЬ @count = 1; В то время как @Count <= 10 BEGIN Установите @MOD = @Count % 2 IF @MOD = 1 BERNAL SET @Count = @Count + 1; ПРОДОЛЖИТЬ КОНЕЦ PRINT @count SET @count = @count + 1; КОНЕЦ; |
В приведенном выше скрипте цикл while выполняется до тех пор, пока значение переменной @count не станет меньше или равно 10. Начальное значение переменной @count равно 1.
В теле цикла значение остатка от деления @count на 2 сохраняется в переменной @mod. Если значение переменной @count нечетное, остаток будет равен 1, а если остаток равен 0, оператор CONTINUE используется для возврата управления к началу цикла while, а значение переменной @count не напечатано.
В противном случае значение переменной @count выводится на консоль. Вот вывод вышеуказанного скрипта:
В следующем примере показано использование оператора BREAK. Цикл while в следующем скрипте будет завершаться после печати первых пяти целых чисел:
1 2 3 4 5 6 7 8 9 10 11 12 | DECLARE @count INT; УСТАНОВИТЬ @count = 1; В то время как @Count <= 10 BEGIN IF @Count> 5 BEGIN BREAK END PRINT @Count SET @Count = @Count + 1; КОНЕЦ; |
Заключение
Если вы хотите многократно выполнять определенный SQL-скрипт, вам подойдет цикл SQL While. В статье объясняется, как использовать цикл SQL While в Microsoft SQL Server для выполнения различных задач, от вставки записи до разбиения на страницы.
- Автор
- Последние сообщения
Бен Ричардсон
Бен Ричардсон управляет Acuity Training, ведущим поставщиком обучения SQL в Великобритании. Он предлагает полный спектр обучения SQL от вводных курсов до продвинутого обучения администрированию и работе с хранилищами данных — см. здесь для получения более подробной информации. Acuity имеет офисы в Лондоне и Гилфорде, графство Суррей. Он также иногда пишет в блоге Acuity
Просмотреть все сообщения Бена Ричардсона
Последние сообщения Бена Ричардсона (см. все)
ПОКА (Transact-SQL) — SQL Server
Редактировать
Твиттер LinkedIn Фейсбук Эл. адрес
- Статья
- 2 минуты на чтение
Применимо к: SQL Server (все поддерживаемые версии) База данных SQL Azure Управляемый экземпляр Azure SQL Аналитика синапсов Azure Система аналитической платформы (PDW)
Задает условие для повторного выполнения оператора SQL или блока операторов. Операторы выполняются многократно, пока заданное условие истинно. Выполнение операторов в цикле WHILE можно контролировать изнутри цикла с помощью ключевых слов BREAK и CONTINUE.
Соглашения о синтаксисе Transact-SQL
Синтаксис
-- Синтаксис для SQL Server и базы данных SQL Azure WHILE Boolean_expression { sql_statement | блок_операторов | ПЕРЕРЫВ | ПРОДОЛЖАТЬ }
-- Синтаксис для Azure Azure Synapse Analytics и хранилища параллельных данных WHILE Boolean_expression { sql_statement | блок_операторов | ЛОМАТЬ }
Примечание
Для просмотра синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий см. документацию по предыдущим версиям.
Аргументы
Boolean_expression
Выражение, возвращающее TRUE или FALSE . Если логическое выражение содержит оператор SELECT, оператор SELECT должен быть заключен в круглые скобки.
{ sql_statement | statement_block }
Любой оператор Transact-SQL или группа операторов, определенная с помощью блока операторов. Чтобы определить блок операторов, используйте ключевые слова управления потоком BEGIN и END.
BREAK
Вызывает выход из самого внутреннего цикла WHILE. Любые операторы, которые появляются после ключевого слова END, обозначающего конец цикла, выполняются.
CONTINUE
Запускает цикл WHILE, игнорируя все операторы после ключевого слова CONTINUE.
Если два или более цикла WHILE вложены друг в друга, внутренний BREAK переходит к следующему самому внешнему циклу. Сначала выполняются все операторы после окончания внутреннего цикла, а затем перезапускается следующий внешний цикл.
Примеры
A. Использование BREAK и CONTINUE с вложенными IF…ELSE и WHILE
В следующем примере, если средняя прейскурантная цена продукта меньше $300
, цикл WHILE
удваивает цены а затем выбирает максимальную цену. Если максимальная цена меньше или равна $500
, цикл WHILE
перезапускается и снова удваивает цены. Этот цикл продолжает удваивать цены до тех пор, пока максимальная цена не превысит $500
, а затем выходит из цикла WHILE
и печатает сообщение.
ИСПОЛЬЗОВАТЬ AdventureWorks2012; ИДТИ ПОКА (ВЫБЕРИТЕ СРЕДНЮЮ (ListPrice) ИЗ Production.Product) < $300 НАЧИНАТЬ ОБНОВЛЕНИЕ Производство.Продукт УСТАНОВИТЬ СписокЦена = СписокЦена * 2 SELECT MAX (ListPrice) FROM Production.Product ЕСЛИ (ВЫБЕРИТЕ МАКС.(СписокЦен) ИЗ Производство.Продукт) > 500 долл. США ЛОМАТЬ ЕЩЕ ПРОДОЛЖАТЬ КОНЕЦ PRINT «Слишком много для рынка»;
B. Использование WHILE в курсоре
В следующем примере используется @@FETCH_STATUS
для управления действиями курсора в цикле WHILE
.
ОБЪЯВИТЬ @EmployeeID как NVARCHAR(256) DECLARE @Title как NVARCHAR(50) DECLARE Employee_Cursor CURSOR FOR ВЫБЕРИТЕ LoginID, JobTitle ОТ AdventureWorks2012.HumanResources.Employee ГДЕ JobTitle = 'Специалист по маркетингу'; ОТКРЫТЬ Сотрудник_Курсор; FETCH NEXT FROM Employee_Cursor INTO @EmployeeID, @Title; ПОКА @@FETCH_STATUS = 0 НАЧИНАТЬ Вывести ' ' + @EmployeeID + ' '+ @Title FETCH NEXT FROM Employee_Cursor INTO @EmployeeID, @Title; КОНЕЦ; ЗАКРЫТЬ Сотрудник_Курсор; DEALLOCATEEmployee_Cursor; ИДТИ
Примеры: Azure Synapse Analytics and Analytics Platform System (PDW)
C: простой цикл While
цены, а затем выбирает максимальную цену. Если максимальная цена меньше или равна $500
, цикл WHILE
перезапускается и снова удваивает цены. Этот цикл продолжает удваивать цены до тех пор, пока максимальная цена не превысит 9.0665 $500 , а затем выходит из цикла WHILE
.
-- Использует AdventureWorks ПОКА (ВЫБРАТЬ AVG(ListPrice) FROM dbo. DimProduct) < $300 НАЧИНАТЬ ОБНОВЛЕНИЕ dbo.DimProduct УСТАНОВИТЬ СписокЦена = СписокЦена * 2; ВЫБЕРИТЕ МАКСИМАЛЬНОЕ (ListPrice) ИЗ dbo.DimProduct ЕСЛИ ( ВЫБЕРИТЕ МАКСИМАЛЬНУЮ (ListPrice) ИЗ dbo.DimProduct) > 500 долларов США ЛОМАТЬ; КОНЕЦ
См. также
ALTER TRIGGER (Transact-SQL)
Язык управления потоком (Transact-SQL)
CREATE TRIGGER (Transact-SQL)
Курсоры (Transact-SQL)
SELECT (Transact-SQL)
SQL Server WHILE LOOP — javatpoint
следующий → ← предыдущая В этой статье вы найдете полный обзор использования цикла WHILE в SQL Server. Цикл WHILE — это оператор потока управления, используемый для многократного выполнения набора операторов до тех пор, пока не будет выполнено указанное условие . Этот цикл начинается с заданного условия, оцените его, и если оно ИСТИНА, операторы перейдут внутрь цикла для дальнейшего выполнения. Если условие становится FALSE, оно не будет выполняться. Это означает, что цикл while в SQL Server может выполняться ноль или более раз. Блок-схема цикла WHILEСледующая блок-схема объясняет полный рабочий процесс цикла WHILE в SQL Server: На этой диаграмме видно, что указанное условие проверяется для каждой итерации, и на основе результата оценки определяется поток кода. Если результат оценивается как TRUE, поток управления переходит внутрь цикла для дальнейшего выполнения. Если оцениваемый результат равен FALSE, поток управления выйдет из цикла, и будет выполнен любой оператор или запрос вне цикла. СинтаксисСледующий синтаксис иллюстрирует цикл WHILE в SQL Server: ПОКА логическое_условие НАЧИНАТЬ {выражение_SQL | блок_операторов | ПЕРЕРЫВ | ПРОДОЛЖАТЬ} КОНЕЦ; В этом синтаксисе у нас есть следующие параметры или аргументы:
Пример цикла WHILEДавайте разберемся, как работает цикл WHILE в SQL Server, на примере. В данном примере мы сначала объявили значение целочисленного типа и установили его значение в 1. Затем цикл WHILE проверяет условие, и если оно TRUE , будет напечатан оператор печати. Когда цикл становится FALSE , будет напечатан следующий оператор после цикла WHILE. DECLARE @stud_value INT; УСТАНОВИТЬ @stud_value = 1; ПОКА @stud_value Выполнение этого оператора вернет следующий вывод: В приведенном выше фрагменте кода цикла WHILE мы должны увеличивать значение переменной после каждой итерации. См. нижнюю часть приведенной выше строки кода как SET @stud_value = @stud_value + 1 . Если мы не напишем этот оператор, цикл будет выполняться бесконечно, потому что он не может стать FALSE. НАЧИНАТЬ ПЕЧАТЬ ‘Марк Генри’; SET @stud_value = @stud_value + 1; КОНЕЦ; Бесконечный цикл WHILEВозникает бесконечный цикл, когда оценка условия никогда не будет ложной. Следовательно, цикл никогда не закончится и будет выполняться вечно. Цикл в следующем фрагменте кода бесконечен, поскольку значение переменной не увеличивается. DECLARE @stud_value INT; УСТАНОВИТЬ @stud_value = 1; ПОКА @stud_value Выполнение цикла отобразит следующий вывод. Этот цикл никогда не завершит свое выполнение, пока мы не отменим их выполнение запроса вручную. Вставка записей с помощью цикла WHILEМы также можем использовать цикл WHILE для вставки записей в определенную таблицу. Давайте посмотрим, как вставлять фиктивные записи в базу данных. Сначала мы создадим таблицу с именем ‘bikeshop’ , содержащую три столбца: Id, bike_name, и price . Выполните следующую инструкцию, чтобы создать эту таблицу: СОЗДАТЬ СТОЛ магазин велосипедов ( Id INT PRIMARY KEY IDENTITY, имя_велосипеда VARCHAR (50) НЕ НУЛЕВОЕ, цена с плавающей запятой ) Далее мы будем использовать цикл WHILE для вставки десяти записей в эту таблицу, выполнив следующий скрипт: DECLARE @count INT; УСТАНОВИТЬ @количество = 1; ПОКА @count В этом коде мы объявили переменную @ count , а затем инициализировали ее значение 1 с помощью предложения SET. Затем мы должны определить тело цикла, которое выполняет инструкцию INSERT, чтобы добавить одну запись при каждом выполнении. Столбец bike_name добавит значение переменной @count со строкой 9.0235 Bike , а столбец price определяется значением переменной @count, умноженным на 5000 . Цикл будет выполняться до тех пор, пока значение переменной @count не станет FALSE. Это означает, что цикл WHILE будет выполнен десять раз, и вставит десять записей в таблицу bikeshop. Теперь мы можем проверить все записи таблицы bikeshop с помощью оператора SELECT. Он отобразит следующий вывод: Оператор BREAKSQL Server также позволяет нам использовать оператор BREAK в цикле WHILE, подобно языкам программирования. Это утверждение используется для немедленно останавливает текущую итерацию цикла , и поток управления возобновляется со следующего оператора после цикла. В общем, мы будем использовать оператор IF…ELSE , чтобы проверить, произошло ли условие. В следующем примере показано, как использовать оператор BREAK в цикле WHILE: DECLARE @count INT; УСТАНОВИТЬ @количество = 1; ПОКА @count = 6 НАЧИНАТЬ ЛОМАТЬ КОНЕЦ УСТАНОВИТЬ @Count = @Count + 1 КОНЕЦ; Выполнение кода отобразит следующий вывод: Сначала в этом коде оценивается значение переменной. Если это TRUE, элемент управления входит в цикл и печатает оператор. Когда значение переменной больше или равно 6, управление переходит в блок IF…ELSE и выполняет оператор BREAK для завершения цикла. Если блок IF…ELSE не удовлетворяет условию; затем цикл будет продолжать работать до тех пор, пока условие не изменится на FALSE. ПРОДОЛЖИТЬ ЗаявлениеSQL Server также позволяет нам использовать оператор CONTINUE в цикле WHILE, подобно языкам программирования. Этот оператор немедленно завершает текущее выполнение цикла при выполнении указанного условия , и поток управления возвращается к началу цикла. Как правило, оператор IF…ELSE будет использоваться для проверки того, было ли выполнено условие. Оператор CONTINUE в цикле WHILE демонстрируется в следующем примере. В этом примере мы предположим, что хотим использовать цикл WHILE для печатать только нечетные значения . Для этого можно использовать оператор CONTINUE. В этом примере сначала проверит , является ли значение переменной нечетным или четным . Если оно четное, выполнение переходит в блоки операторов IF…ELSE и уменьшает значение переменной на единицу. Затем он выполнит оператор CONTINUE и начнет новую итерацию с самого начала. DECLARE @Count INT УСТАНОВИТЬ @Count = 1 ПОКА (@Count )Выполнение фрагмента кода отобразит следующий вывод: Как реализовать пейджинг с циклом WHILE в SQL Server?Мы также можем использовать цикл WHILE для реализации пейджинга. Пейджинг позволяет отображать подмножество записей из таблицы в любой момент времени. Следующий пример пояснит эту концепцию. Цикл WHILE в коде будет выбирать две записи из таблицы bikeshop за раз. Выбранные записи затем отображаются в выходных данных. DECLARE @count INT ОБЪЯВИТЬ @limit INT; УСТАНОВИТЬ @количество = 0 УСТАНОВИТЬ @лимит = 2; ПОКА @count Выполнение фрагмента кода вернет следующий вывод: Вложенный цикл WHILEВложенный цикл WHILE в SQL Server — это просто цикл WHILE, записанный внутри другого цикла WHILE. Когда мы работаем с многоуровневыми данными, вложенные циклы WHILE необходимы. Поскольку эта концепция полезна при извлечении многоуровневых данных, когда мы хотим их выбрать, рекомендуется соблюдать осторожность при использовании вложенного цикла. Синтаксис Следующий синтаксис иллюстрирует работу вложенного цикла WHILE в SQL Server: В то время как выражение НАЧИНАТЬ ПОКА @Val2 Давайте объясним этот синтаксис шаг за шагом: Шаг 1: Цикл начинается с проверки первого условия цикла WHILE, и если он находит ложный результат, он выходит из цикла While. В противном случае, если результат верен, управление переходит внутрь блока BEGIN и END для дальнейшего выполнения. Этот блок запустит выполнение второго цикла WHILE. См. шаг 2. Шаг 2: На этом шаге проверяется условие во вложенном цикле WHILE, и если оно ложно, второй цикл завершается и выполняется оператор вне этого. В противном случае, если результат верен, управление переходит внутрь блока BEGIN и END для дальнейшего выполнения. Шаг 3: После выполнения всех операторов из второго цикла WHILE управление переходит к первому циклу WHILE и повторяет первый шаг. Пример В следующем примере будет напечатана таблица умножения от 5 до 10 с использованием вложенного цикла WHILE. ОБЪЯВИТЬ @val1 INT ОБЪЯВИТЬ @val2 INT УСТАНОВИТЬ @val1 = 5 УСТАНОВИТЬ @val2 = 1 ПОКА @val1 Выполнение инструкции отобразит таблицу умножения 5. Вот вывод: Цикл WHILE является полезным методом, когда необходимо повторно выполнить сценарий SQL. В статье объяснялось, как работать с циклом WHILE в MS SQL Server для выполнения таких операций, как вставка записи и разбиение на страницы, на простом примере. Здесь мы также изучили операторы BREAK и CONTINUE для управления итерацией цикла WHILE. Следующая темаПоиск и удаление дубликатов из таблицы в SQL Server ← предыдущая следующий → |
Структура принятия решений, которую вы должны знать
Время чтения: 7 минут
Цикл WHILE — это один из основных инструментов, который вы должны знать, когда впервые начинаете работать с Microsoft SQL Server.
Иногда при работе с SQL Server требуется, чтобы определенный код выполнялся несколько раз в цикле, пока выполняется какое-то условие. Как только это условие становится ложным, выполнение цикла прекращается.
Цикл WHILE — это инструмент, который мы можем использовать для достижения этой цели.
Этот цикл WHILE является одной из нескольких структур принятия решений, доступных нам в SQL Server. Другой полезной структурой принятия решений является структура IF…ELSE IF….ELSE. Это еще одна очень распространенная структура принятия решений, которую вы, вероятно, увидите и будете использовать как профессионал в области баз данных, поэтому важно, чтобы вы также понимали, как она работает. Если вы пропустили учебник по этому вопросу, вы должны проверить его.
Заявление IF…ELSE IF…ELSE: все, что вы должны знать.
В этом уроке мы поговорим только о трех темах цикла WHILE:
- Что такое цикл WHILE?
- Пример использования цикла WHILE
- Советы, рекомендации и ссылки
Приступим.
1. Что такое цикл WHILE?
Цикл WHILE используется для многократного выполнения блока кода, пока выполняется какое-либо условие. Каждая итерация цикла должна двигаться к тому, чтобы сделать наше условие ложным. Как только это условие становится ложным, цикл останавливается.
Вот основная схема и синтаксис цикла WHILE:
WHILE(<условие истинно>) НАЧИНАТЬ <выполнить некоторый код> <движение к тому, чтобы сделать условие ложным> КОНЕЦ
Каждая итерация цикла должна продвигать цикл к тому, чтобы сделать условие ложным. В начале каждой итерации цикла он проверяет, действительно ли наше условие ложно .
Есть несколько вещей, которые вы должны знать о синтаксисе цикла WHILE:
- Ключевые слова BEGIN…ELSE должны присутствовать, если тело цикла WHILE состоит более чем из одной строк. Если ваше тело состоит всего из одной строки, вы можете пропустить эти ключевые слова. Но, честно говоря, я не уверен, как вы могли бы иметь цикл WHILE длиной всего в одну строку.
- Круглые скобки вокруг проверки условия цикла WHILE являются необязательными . Мне нравится использовать круглые скобки, потому что я думаю, что это делает код более читабельным.
Теперь, когда мы знаем синтаксис и общую идею, давайте рассмотрим несколько примеров в следующем разделе.
2. Пример использования цикла WHILE
Давайте начнем с очень простого примера, чтобы дать вам представление.
Допустим, мы хотим просто вывести на экран числа от 1 до 12 . Мы можем достичь этого трудным путем , выполнив следующее:
Но опять же, это был трудный путь. Вместо этого мы можем использовать цикл, чтобы сделать то же самое с меньшим количеством строк кода:
Давайте разберем, что происходит в цикле. Во-первых, проверьте @count переменная, которую мы используем:
Мы используем эту переменную @count для продвижения нашего цикла вперед.
Проверяется условие, если @count меньше 13 . В первом запуске цикла @count — это просто 1 , потому что это значение, которое мы установили. Поскольку 1 меньше 13 , мы вводим тело цикла:
В теле цикла мы делаем две вещи. Мы просто печатаем текущее значение @count , а затем увеличиваем нашу переменную @count на 1 .
Что касается первой части, обратите внимание, что нам нужно было использовать функцию CONVERT для преобразования нашего целого числа @count в тип данных строки символов. Системная функция печати требует, чтобы все было в формате строки символов. Мы решили использовать символьный тип данных VARCHAR.
Нужно кое-что узнать о символьных типах данных? Я понял:
Символьные типы данных SQL Server (и различия между ними)
Второе, на что следует обратить внимание в теле цикла, это то, как мы увеличиваем нашу переменную @count на 1. Это очень важно .
Тело цикла while должно перемещать цикл вперед, к завершению цикла.
Когда мы увеличиваем @count , мы перемещаем его все ближе и ближе к числу 13 , что завершит цикл . Помните условие, которое мы проверяем? Мы продолжаем проходить цикл, пока наша @count переменная меньше 13 .
В конце 12-го запуска цикла наша переменная @count будет снова увеличена на 1 , как обычно. Таким образом, он будет установлен на 13 . Затем мы доходим до проверки условия:
Значит, число 13 меньше, чем 13 ?
Нет. Так что же происходит?
Мы под залог. Цикл заканчивается.
Что, если мы забыли включить последнюю строку тела, где мы увеличиваем @count на 1? Переменная @count никогда не изменит по сравнению с исходным значением 1 , что означает, что наше условие всегда будет истинным, НАВСЕГДА.
Это, друзья мои, то, что мы называем бесконечным циклом и
(Кроме того, мне пришлось вручную завершить запрос, чтобы остановить его. Если бы я этого не сделал, одному Богу известно, как долго он выполнялся бы.)
Вы можете отнести в банк следующее заявление: В какой-то момент своей карьеры вы обязательно напишете бесконечный цикл. Очевидно, что это будет случайность, но это произойдет.
Поверьте мне, я профессионал бесконечного цикла на данный момент.
Реальный пример цикла WHILE
Давайте подумаем о лучшем реальном примере использования цикла WHILE.
Допустим, у нас есть розничный магазин в городе Боулдер, штат Колорадо. У нас есть таблица BoulderStore для хранения основной информации о клиентах. Взгляните на содержимое этой таблицы:
Круто. Обратите внимание, что значения CustID : от 1 до 12.
Если мы хотим напечатать адрес электронной почты каждого клиента , мы можем легко добиться этого с помощью цикла WHILE:
Давайте разберем и это.
В начале цикла мы намечаем переменную, которую будем использовать для перемещения цикла вперед, и определяем условие для нашего цикла:
(Обратите внимание, что на этот раз я не использовал круглые скобки вокруг своего условия. Опять же, использование скобок необязательно )
Затем в теле цикла мы создаем простую переменную @emailAddr . Мы заполняем эту переменную адресом электронной почты клиента, чей идентификатор клиента соответствует @IDVal мы сейчас находимся:
Затем мы печатаем собранную информацию и увеличиваем нашу переменную условия:
Не забудьте изменить свою переменную условия ! Он должен двигаться в направлении окончания цикла!
Использование циклов WHILE в курсорах
Примеры в этом руководстве предназначены для ознакомления с циклами WHILE и принципами их работы. Подобные примеры можно использовать и в реальном мире, но чаще всего цикл WHILE используется в реальном мире в Курсоры .
Информации о создании и использовании курсоров SQL Server достаточно, чтобы оправдать собственное руководство. Обязательно ознакомьтесь с этим:
Курсоры SQL Server: практическое руководство
Опять же, вы, скорее всего, будете использовать циклы WHILE внутри курсоров, так что вы определенно должны быть с ними знакомы.
3. Советы, рекомендации и ссылки
Вот список советов и рекомендаций, которые вы должны знать о цикле WHILE:
В цикле WHILE может быть несколько условий
Конечно, вы можете иметь более одной проверки условия цикла WHILE. Вы можете разделить свои чеки, используя операторы И или ИЛИ . Но помните, вам нужно убедиться, что все условие в конечном итоге оценивается как false , завершая цикл.
Дополнительную информацию об операторах AND и OR можно найти в учебнике IF…ELSE IF…ELSE:
Заявление IF…ELSE IF…ELSE: все, что вам следует знать.
Ссылки
Существует отличная книга под названием T-SQL Fundamentals, написанная Ициком Бен-Ганом , в которой рассматриваются несколько основных концепций, которые вам следует знать о SQL Server, включая создание циклов WHILE. Это одна из немногих книг, которые помогли мне понять многие темы SQL Server. Вы не пожалеете, что приобрели эту книгу, , поверьте мне, . Обязательно получи сегодня!
Следующие шаги:
Убедитесь, что вы прочитали полное руководство по курсорам SQL Server. Курсоры — это то место, где вы, скорее всего, увидите и используете цикл WHILE, поэтому вы должны убедиться, что понимаете, как они работают:
Курсоры SQL Server: практическое руководство.
Как упоминалось ранее, структура IF…ELSE IF…ELSE — еще одна очень распространенная структура принятия решений, которую вы, вероятно, увидите и будете использовать как профессионал в области баз данных. Важно, чтобы вы тоже понимали, как это работает. Вот ссылка:
Заявление IF…ELSE IF…ELSE: все, что вы должны знать.
Скорее всего, вы увидите и будете использовать эти структуры принятия решений в своих хранимых процедурах . Если вам нужно подробно обсудить, что такое хранимые процедуры и как они могут нам помочь, ознакомьтесь с этим руководством:
Хранимые процедуры: полное руководство для начинающих
Большое спасибо за внимание!
Не забудьте подписаться на мою рассылку, чтобы получать специальные предложения и уведомления каждый раз, когда выходит новый учебник!
Если у вас есть вопросы, пожалуйста, оставьте комментарий . Или еще лучше, пришлите мне письмо!
SQL Server WHILE Циклы
Этот веб-сайт использует файлы cookie. Используя сайт, вы принимаете политику использования файлов cookie. Это сообщение соответствует законодательству Великобритании об ICO.
SQL 2005+
Ричарда Карра, опубликовано на http://www.blackwasp. co.uk/sqlwhile.aspx
В пятьдесят пятой части учебника по основам программирования SQL Server рассматриваются языки Transact-SQL (T-SQL ) ПОКА заявление. Эта мощная команда управления потоком позволяет создавать циклические структуры в сценариях и хранимых процедурах.
Предыдущий: Условия IF SQL Server
Петли
Циклические структуры позволяют многократно выполнять одну команду или группу операторов. При использовании цикла T-SQL WHILE логическое условие проверяется каждый раз перед запуском кода внутри цикла. Если условие истинно, цикл выполняется. Если нет, управление переходит к оператору, следующему за циклом.
ЦиклыWHILE обычно используются с курсорами, которые описаны в следующей статье этого руководства, для обработки набора данных по одной строке за раз. В этой статье мы сконцентрируемся на структуре цикла на простых примерах, которые можно выполнить напрямую, без доступа к базе данных.
Использование циклов WHILE
Синтаксис создания цикла while следующий:
ПОКА условие условия
Этот синтаксис аналогичен основному синтаксису оператора IF, который мы видели в предыдущей статье. Условие Элемент определяет значение, переменную или выражение, которое оценивается как истинное или ложное. Если значение равно true, выполняется оператор , часть команды. После завершения условие снова проверяется, и процесс продолжается до тех пор, пока условие не станет ложным. NB: элемент оператора может содержать несколько команд, если они появляются между командами BEGIN и END.
Мы можем продемонстрировать цикл, выполнив сценарий в SQL Server Management Studio или в предпочитаемой вами среде для запуска T-SQL. Следующий сценарий объявляет переменную и инициализирует ее значение нулем. Условие цикла указывает, что содержащиеся операторы будут выполняться, пока значение переменной меньше или равно десяти. В цикле значение переменной увеличивается и печатается. Конечным результатом является то, что выводятся целые числа от одного до десяти.
DECLARE @Iteration INT УСТАНОВИТЕ @Итерация = 1 ПОКА @Итерация <= 10 НАЧИНАТЬ ПЕЧАТЬ @Итерация УСТАНОВИТЬ @Итерация = @Итерация + 1 КОНЕЦ
Явный выход из цикла
Иногда вам может понадобиться завершить цикл, даже если часть условия верна. Этого можно добиться с помощью команды BREAK . Эта команда указывает, что управление должно передаваться команде, следующей за текущим циклом.
В следующем примере скрипта цикл вычисляет квадраты значений от одного до девяноста девяти. Оператор IF проверяет, превышает ли результат возведения в квадрат тысячу. В первый раз, когда это происходит, цикл завершается, хотя переменная @ToSquare по-прежнему меньше сотни.
DECLARE @ToSquare INT ОБЪЯВИТЬ @Square INT УСТАНОВИТЕ @ToSquare = 0 ПОКА @ToSquare < 100 НАЧИНАТЬ НАБОР @ToSquare = @ToSquare + 1 SET @Square = @ToSquare * @ToSquare ЕСЛИ @Квадрат > 1000 ЛОМАТЬ ПЕЧАТЬ @Square КОНЕЦ
Перезапуск цикла
Если вы хотите завершить одну итерацию цикла, вы можете использовать команду CONTINUE . Эта команда немедленно останавливает текущую итерацию и повторно проверяет состояние цикла. Если условие по-прежнему верно, цикл перезапускается. В следующем примере оператор CONTINUE и оператор BREAK комбинируются так, что выводятся квадраты от ста до одной тысячи.