While цикл sql: MS SQL Server и T-SQL

Содержание

MS SQL Server и T-SQL

Циклы

Последнее обновление: 14.08.2017

Для выполнения повторяющихся операций в T-SQL применяются циклы. В частности, в T-SQL есть цикл WHILE. Этот цикл выполняет определенные действия, пока некоторое условие истинно.


WHILE условие
	{инструкция|BEGIN...END}

Если в блоке WHILE необходимо разместить несколько инструкций, то все они помещаются в блок BEGIN…END.

Например, вычислим факториал числа:


DECLARE @number INT, @factorial INT
SET @factorial = 1;
SET @number = 5;

WHILE @number > 0
	BEGIN
		SET @factorial = @factorial * @number
		SET @number = @number - 1
	END;

PRINT @factorial

То есть в данном случае пока переменная @number не будет равна 0, будет продолжаться цикл WHILE. Так как @number равна 5, то цикл сделает пять проходов. Каждый проход цикла называется итерацией. В каждой итерации будет переустанавливаться значение переменных @factorial и @number.

Другой пример — рассчитаем баланс счета через несколько лет с учетом процентной ставки:


USE productsdb;

CREATE TABLE #Accounts ( CreatedAt DATE, Balance MONEY)

DECLARE @rate FLOAT, @period INT, @sum MONEY, @date DATE
SET @date = GETDATE()
SET @rate = 0.065;
SET @period = 5;
SET @sum = 10000;

WHILE @period > 0
	BEGIN
		INSERT INTO #Accounts VALUES(@date, @sum)
		SET @period = @period - 1
		SET @date = DATEADD(year, 1, @date)
		SET @sum = @sum + @sum * @rate
	END;

SELECT * FROM #Accounts

Здесь создается временная таблица #Accounts, в которую добавляется в цикле пять строк с данными.

Операторы BREAK и CONTINUE

Оператор BREAK позволяет завершить цикл, а оператор CONTINUE — перейти к новой итерации.


DECLARE @number INT
SET @number = 1

WHILE @number < 10
	BEGIN
		PRINT CONVERT(NVARCHAR, @number)
		SET @number = @number + 1
		IF @number = 7
			BREAK;
		IF @number = 4
			CONTINUE;
		PRINT 'Конец итерации'
	END;

Когда переменная @number станет равна 4, то с помощью оператора CONTINUE произойдет переход к новой итерации, поэтому последующая строка PRINT 'Конец итерации' не будет выполняться, хотя цикл продолжится.

Когда переменная @number станет равна 7, то оператор BREAK произведет выход из цикла, и он завершится.

Цикл WHILE для выбора данных за период в T-SQL — Разработка на vc.ru

Зачастую в нашей работе возникает потребность получить набор данных за определенный период. Сделать это можно несколькими способами. В этой статье рассмотрим применение цикла WHILE для задачи поиска расходных операций за несколько месяцев по перечню счетов и сравним его с запросом, в котором весь период будет указан в блоке WHERE.

Зачастую в нашей работе возникает потребность получить набор данных за определенный период. Сделать это можно несколькими способами. В этой статье рассмотрим применение цикла 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

WHILE LOOP SQL Server — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

В этом учебном пособии вы узнаете, как использовать WHILE LOOP в SQL Server (Transact-SQL) с синтаксисом и примерами.

Описание

В SQL Server WHILE LOOP используется тогда, когда вы не уверены, сколько раз вы будет выполняться тело цикла, и тело цикла может не выполняться даже один раз.

Синтаксис

Синтаксис WHILE LOOP в SQL Server (Transact-SQL):

WHILE condition
BEGIN
{… statements…}
END;

Параметры или аргументы

condition – условие, которое проверяется при каждом прохождении через цикл. Если условие имеет значение TRUE, выполняется тело цикла. Если условие оценивается как FALSE, цикл завершается.
statements — кода для выполнения при каждом прохождении через цикл.

Примечание

  • Вы должны использовать инструкцию WHILE LOOP, если не знаете, сколько раз вы хотите, чтобы тело цикла выполнялось.
  • Поскольку условие WHILE оценивается перед входом в цикл, возможно, что тело цикла может не выполняться даже один раз.
  • См. также оператор BREAK для выхода из WHILE LOOP раньше.
  • См. также оператор CONTINUE для перезапуска WHILE LOOP с самого начала.

Пример

Рассмотрим пример использования WHILE LOOP в SQL Server (Transact-SQL).

Например:

DECLARE @site_id INT; SET @site_id = 0; WHILE @site_id <= 10 BEGIN PRINT ‘Inside WHILE LOOP on yandex.com’; SET @site_id = @site_id + 1; END; PRINT ‘Done WHILE LOOP on yandex.com’; GO

DECLARE @site_id INT;

SET @site_id = 0;

 

WHILE @site_id <= 10

BEGIN

   PRINT ‘Inside WHILE LOOP on yandex.com’;

   SET @site_id = @site_id + 1;

END;

 

PRINT ‘Done WHILE LOOP on yandex.com’;

GO

В этом примере WHILE LOOP цикл завершится, как только значение @site_id превысит 10, как указано в строке:

WHILE LOOP будет продолжаться в то время как @site_id @site_id будет > 10, цикл завершится.

Вы также можете использовать WHILE LOOP в курсоре.
Например:

DECLARE contacts_cursor CURSOR FOR SELECT contact_id, site_id FROM contacts; OPEN contacts_cursor; FETCH NEXT FROM contacts_cursor; WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM contacts_cursor; PRINT ‘Inside WHILE LOOP on Yandex.com’; END; PRINT ‘Done WHILE LOOP on Yandex.com’; CLOSE contacts_cursor; DEALLOCATE contacts_cursor; GO

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

DECLARE contacts_cursor CURSOR FOR

SELECT contact_id, site_id

FROM contacts;

 

OPEN contacts_cursor;

FETCH NEXT FROM contacts_cursor;

 

WHILE @@FETCH_STATUS = 0

   BEGIN

      FETCH NEXT FROM contacts_cursor;

      PRINT ‘Inside WHILE LOOP on Yandex.com’;

   END;

PRINT ‘Done WHILE LOOP on Yandex.com’;

 

CLOSE contacts_cursor;

DEALLOCATE contacts_cursor;

GO

В этом примере WHILE LOOP цикл прекращается, как только @@FETCH_STATUS больше не равен 0, как указано:

Цикл 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 строк.

Данный способ позволяет быстрее получить необходимые данные, так как при каждом выполнении будет использоваться индекс на дату, и, если в результате выполнения запроса случится какая-либо ошибка, сохранить результат ранее отработанных шагов цикла.

WHILE оператор MySQL — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

В этом учебном пособии вы узнаете, как использовать оператор WHILE (WHILE LOOP) в MySQL с синтаксисом и примерами.

Описание

В MySQL оператор WHILE используется тогда, когда вы не знаете, сколько раз будет выполняться тело цикла, и тело цикла может не выполняться даже один раз.

Синтаксис

Синтаксис инструкции WHILE в MySQL:

[ label_name: ] WHILE condition DO
{…statements…}
END WHILE [ label_name ];

Параметры или аргументы

label_name — необязательный. Это наименование связано с циклом WHILE.
condition — условие которое проверяется при каждой итерации цикла WHILE. Если condition примет значение TRUE, тело цикла выполняется. Если условие принимает значение FALSE, цикл WHILE прекращается.
statements — код, выполняемый при каждом, проходе через цикл WHILE.

Примечание

  • Вы должны использовать оператор WHILE LOOP, если не знаете сколько раз должно выполняться тело цикла.
  • Поскольку condition WHILE оценивается перед входом в цикл, то возможно, что тело цикла может не выполняться даже один раз.

Пример

Рассмотрим пример, показывающий как использовать оператор WHILE в MySQL:

DELIMITER // CREATE FUNCTION CalcCost ( starting_value INT ) RETURNS INT BEGIN DECLARE cost INT; SET cost = 0; label1: WHILE cost <= 3000 DO SET cost = cost + starting_value; END WHILE label1; RETURN cost; END; // DELIMITER ;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

DELIMITER //

 

CREATE FUNCTION CalcCost ( starting_value INT )

RETURNS INT

 

BEGIN

 

   DECLARE cost INT;

 

   SET cost = 0;

 

   label1: WHILE cost <= 3000 DO

     SET cost = cost + starting_value;

   END WHILE label1;

 

   RETURN cost;

 

END; //

 

DELIMITER ;

В этом примере WHILE LOOP цикл будет прекращаться, как только cost превысит 3000, как указано:

label1: WHILE cost <= 3000 DO

label1: WHILE cost <= 3000 DO

WHILE LOOP будет продолжаться с cost cost будет> 3000, цикл прекратится.

Использование курсоров и циклов в 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.

Нравится8Не нравится

server — Как интегрировать цикл while в SQL-запрос? (Повторение последнего результата в столбце)

Я пытаюсь построить запрос в SQL Server Management Studio, используя цикл while для получения окончательного столбца Result.

Допустим, у меня уже есть запрос (My_query), где я извлекаю следующую информацию.

Пример вывода

My_query уже дает мне всю информацию ниже без столбца Result . Мой план состоял в том, чтобы включить цикл while, который позволял бы мне определять правильный статус для каждого Периода и ID. Логика, которую я пытался использовать, была следующей:

Declare i int = 0
Declare j int = 0
Declare buffer int = 0

With My_query as (My query code is here)

Select *,
       Result = 

 while (i  1 and Status_History IS NULL)
                Set Result = buffer
            If (Block  1 and Status_History IS NOT NULL)
                Set Result = Status_History
                Set buffer = Result
        Set j = j+1
        END
    Set i = i+1
    END
From My_query

Решение: Лучший способ, который я нашел для решения этой проблемы, — это создание индекса (помимо «блочного»), который позволяет мне определить конкретные изменения по группам. Индекс присваивает 0 значениям NULL, и каждый раз, когда значение, отличное от NULL, определяется как SUM 1 для индекса. Когда идентификатор меняется, индекс сбрасывается. Это решение намного проще в использовании ресурсов.

Индекс

SUM(CASE 
WHEN(Status_History) IS NULL THEN 0 ELSE 1 END) OVER (PARTITION BY ID ORDER BY Period DESC) AS IND

Решение

WITH DAT AS (My_query)

SELECT *,
CASE WHEN IND = 0 THEN DAT.Current_Status ELSE MAX(DAT.Status_History) OVER ( PARTITION BY DAT.ID, DAT.IND ORDER BY DAT.Period DESC) END AS Result
FROM DAT
ORDER BY ID, Period DESC 
 ID Period  Current_Status  Status_History  IND Block   Result
1012    201903  32  NULL    0   1   32
1012    201902  32  NULL    0   2   32
1012    201901  32  16  1   3   16
1012    201812  32  NULL    1   4   16
1012    201811  32  NULL    1   5   16
1012    201810  32  10  2   6   10
1012    201809  32  NULL    2   7   10
5124    201903  25  NULL    0   1   25
5124    201902  25  23  2   2   23
5124    201901  25  29  3   3   29
5124    201812  25  NULL    4   4   29
5124    201811  25  NULL    5   5   29
5124    201810  25  NULL    6   6   29
5124    201809  25  NULL    7   7   29

Спасибо всем!

Понимание циклов while в SQL Server

Цикл SQL While используется для многократного выполнения определенного фрагмента сценария SQL.

В этой статье рассматриваются некоторые основные функции цикла SQL While в Microsoft SQL Server с помощью примеров.

Синтаксис цикла while SQL

Синтаксис цикла while SQL следующий:

WHILE условие

BEGIN

// SQL-запросы

END;

Цикл while в SQL начинается с ключевого слова WHILE, за которым следует условие, которое возвращает логическое значение i.е. Правда или ложь.

Тело цикла while продолжает выполняться, если условие не возвращает false. Тело цикла while в SQL начинается с блока BEGIN и заканчивается блоком END.

Простой пример: печать чисел с помощью цикла while

Давайте начнем с очень простого примера, в котором мы используем цикл SQL While для вывода первых пяти положительных целых чисел. ценности:

DECLARE @count INT;

НАБОР @count = 1;

WHILE @count <= 5

BEGIN

PRINT @count

SET @count = @count + 1;

КОНЕЦ;

В приведенном выше сценарии мы сначала объявляем переменную целочисленного типа @count и устанавливаем для нее значение 5.

Затем мы выполняем цикл While, который проверяет, меньше ли значение переменной @count или равно 5. Если Переменная @count имеет значение меньше или равно 5, выполняется тело цикла и текущее значение Переменная @count выводится на консоль.

В следующей строке значение переменной @count увеличивается на 1. Цикл While продолжает выполняться, пока значение переменной @count не станет больше 5.Вот результат:

Вставка записей с помощью цикла while

Давайте теперь посмотрим, как цикл SQL While используется для вставки фиктивных записей в таблицу базы данных.

Для этого нам понадобится простая база данных «CarShop»:

Мы создадим одну таблицу, то есть автомобили в базе данных CarShop. В таблице Cars будет три столбца: Id, Name и Цена. Выполните следующий скрипт:

ИСПОЛЬЗОВАТЬ CarShop

СОЗДАТЬ ТАБЛИЦУ Автомобили

(

Id INT PRIMARY KEY IDENTITY (1,1),

Имя VARCHAR (50) NOT NULL,

Price INT

)

Давайте теперь используем цикл While в SQL, чтобы вставить 10 записей в таблицу Cars.Выполните следующий скрипт:

DECLARE @count INT;

НАБОР @count = 1;

WHILE @count <= 10

BEGIN

INSERT INTO Cars VALUES (‘Car -‘ + CAST (@count as varchar), @ count * 100)

SET @count = @count + 1;

КОНЕЦ;

В приведенном выше сценарии мы снова объявляем переменную @count и инициализируем ее значением 1.Затем цикл while выполняется до тех пор, пока значение переменной @count не станет больше 10, что означает, что цикл while выполняется 10 раз.

В теле цикла while запрос INSERT используется для вставки одной записи в таблицу Cars. В столбце Name к значению переменной @count добавляется строка Car- . Для столбца Price таблицы Cars, значение переменной @count умножается на 100.

Теперь, если вы выберете все записи из таблицы Cars с помощью запроса «SELECT * FROM Cars», вы должны увидеть следующий вывод:

Реализация разбиения на страницы с помощью цикла while

Цикл while также можно использовать для реализации разбиения на страницы.Пейджинг относится к отображению подмножества записей из таблицы данных в любой конкретный момент времени.

В следующем скрипте цикл while будет использоваться для одновременного выбора двух записей из таблицы Cars. В выбранные записи затем отображаются в выводе консоли:

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

FETCH NEXT @limit ROWS ONLY

count

КОНЕЦ;

В приведенном выше сценарии мы инициализируем две переменные i.е. @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 для вывода первых пяти положительных значений. четные целые числа:

DECLARE @count INT;

DECLARE @mod INT;

НАБОР @count = 1;

WHILE @count <= 10

BEGIN

set @mod = @count% 2

IF @mod = 1

BEGIN

SET @count = @count + 1;

ПРОДОЛЖИТЬ

КОНЕЦ

ПЕЧАТЬ @count

SET @count = @count + 1;

КОНЕЦ;

В приведенном выше сценарии цикл while выполняется до тех пор, пока значение переменной @count не останется меньше или равным 10.Начальное значение переменной @count — 1.

В теле цикла значение оставшейся части @count, деленной на 2, сохраняется в переменной @mod. Если значение переменной @count нечетное, остаток будет равен 1, а если остаток равен 0, оператор CONTINUE используется для возврата элемента управления в начало цикла while, а значение переменной @count не напечатан.

В противном случае значение переменной @count выводится на консоль.Вот результат выполнения вышеуказанного скрипта:

В следующем примере демонстрируется использование оператора BREAK. Цикл while в следующем скрипте будет завершиться после печати первых пяти целых чисел:

DECLARE @count INT;

НАБОР @count = 1;

WHILE @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

Просмотреть все сообщения Бена Ричардсона

Последние сообщения Бена Ричардсона (посмотреть все) .

SQL Server: В ЦИКЛЕ


В этом руководстве по SQL Server объясняется, как использовать WHILE LOOP в SQL Server (Transact-SQL) с синтаксисом и примерами.

Описание

В SQL Server вы используете WHILE LOOP, когда не уверены, сколько раз вы будете выполнять тело цикла, а тело цикла может не выполняться ни разу.

Синтаксис

Синтаксис WHILE LOOP в SQL Server (Transact-SQL):

 WHILE состояние
НАЧАТЬ
   {...заявления...}
КОНЕЦ; 

Параметры или аргументы

состояние
Условие проверяется при каждом прохождении цикла. Если условие оценивается как ИСТИНА, тело цикла выполняется. Если условие оценивается как ЛОЖЬ, цикл завершается.
ведомостей
Операторы кода для выполнения каждого прохода через цикл.

Примечание

  • Вы можете использовать оператор WHILE LOOP, если не уверены, сколько раз вы хотите, чтобы тело цикла выполнялось.
  • Поскольку условие WHILE оценивается перед входом в цикл, возможно, что тело цикла может выполняться , а не даже один раз.
  • См. Также оператор BREAK для раннего выхода из цикла WHILE LOOP.
  • См. Также оператор CONTINUE, чтобы перезапустить цикл WHILE LOOP с самого начала.

Пример

Давайте рассмотрим пример, который показывает, как использовать WHILE LOOP в SQL Server (Transact-SQL).

Например:

 DECLARE @site_value INT;
НАБОР @site_value = 0;

ПОКА @site_value <= 10
НАЧАТЬ
   ПЕЧАТЬ 'Внутри WHILE LOOP на TechOnTheNet.com ';
   SET @site_value = @site_value + 1;
КОНЕЦ;

ПЕЧАТЬ 'Done WHILE LOOP on TechOnTheNet.com';
GO 

В этом примере WHILE LOOP цикл завершится, когда @site_value превысит 10, как указано в:

 ПОКА @site_value <= 10 

WHILE LOOP будет продолжаться, пока @site_value <= 10. И как только @site_value станет> 10, цикл завершится.

Вы также можете использовать WHILE LOOP в курсоре.

Например:

 ОБЪЯВИТЬ contacts_cursor КУРСОР ДЛЯ
ВЫБЕРИТЕ contact_id, website_id
ОТ контактов;

ОТКРЫТЬ contacts_cursor;
ПОЛУЧИТЬ СЛЕДУЮЩИЙ ОТ contacts_cursor;

ПОКА @@ FETCH_STATUS = 0
   НАЧАТЬ
      ПОЛУЧИТЬ СЛЕДУЮЩИЙ ОТ contacts_cursor;
      ПЕЧАТЬ 'Внутри WHILE LOOP на TechOnTheNet.com ';
   КОНЕЦ;
ПЕЧАТЬ 'Done WHILE LOOP on TechOnTheNet.com';

ЗАКРЫТЬ contacts_cursor;
DEALLOCATE contacts_cursor;
GO 

В этом примере WHILE LOOP цикл завершится, когда @@ FETCH_STATUS больше не будет равно 0, как указано в:

 ПРИ @@ FETCH_STATUS = 0 
.

Oracle PL / SQL WHILE LOOP с примером

  • Home
  • Testing

      • Back
      • Agile Testing
      • BugZilla
      • Cucumber
      • Database Testing
      • Назад
      • JUnit
      • LoadRunner
      • Ручное тестирование
      • Мобильное тестирование
      • Mantis
      • Почтальон
      • QTP
      • Назад
      • Центр качества (ALM3000)
      • Управление тестированием
      • TestLink
  • SAP

      • Назад
      • ABAP 900 04
      • APO
      • Начинающий
      • Basis
      • BODS
      • BI
      • BPC
      • CO
      • Назад
      • CRM
      • Crystal Reports
      • FICO
      • 000
      • 000 HRM
      • 000
      • 000 HRM
      • 9000 Заработная плата
      • Назад
      • PI / PO
      • PP
      • SD
      • SAPUI5
      • Безопасность
      • Менеджер решений
      • Successfactors
      • Учебники SAP

      • Apache
      • AngularJS
      • ASP.Net
      • C
      • C #
      • C ++
      • CodeIgniter
      • СУБД
      • JavaScript
      • Назад
      • Java
      • JSP
      • Kotlin
      • Linux
      • Linux
      • Kotlin
      • Linux
      • js
      • Perl
      • Назад
      • PHP
      • PL / SQL
      • PostgreSQL
      • Python
      • ReactJS
      • Ruby & Rails
      • Scala
      • SQL
      • 000
      • SQL
      • 000 0003 SQL 000 0003 SQL 000
      • UML
      • VB.Net
      • VBScript
      • Веб-службы
      • WPF
  • Обязательно учите!

      • Назад
      • Бухгалтерский учет
      • Алгоритмы
      • Android
      • Блокчейн
      • Business Analyst
      • Создание веб-сайта
      • CCNA
      • Облачные вычисления
      • 00030003 COBOL 9000 Compiler
          9000 Встроенные системы
        • 00030002 9000 Compiler 9000
        • Ethical Hacking
        • Учебники по Excel
        • Программирование на Go
        • IoT
        • ITIL
        • Jenkins
        • MIS
        • Сеть
        • Операционная система
        • Назад
        • Управление проектами Обзоры
        • Salesforce
        • SEO
        • Разработка программного обеспечения
        • VB A
    • Big Data

        • Назад
        • AWS
        • BigData
        • Cassandra
        • Cognos
        • Хранилище данных
        • 0003
        • HBOps
        • 0003
        • HBOps
        • 0003
        • MicroStrategy
        • MongoDB
    .

    SQL Server WHILE - как создать цикл в SQL Server

    Резюме : в этом руководстве вы узнаете, как использовать оператор SQL Server WHILE для повторного выполнения блока операторов на основе указанного условия.

    Обзор оператора WHILE

    Оператор WHILE - это оператор потока управления, который позволяет многократно выполнять блок операторов, пока заданное условие ИСТИНА .

    Ниже показан синтаксис оператора WHILE :

     

    WHILE Boolean_expression {sql_statement | statement_block}

    В этом синтаксисе:

    Во-первых, Boolean_expression - это выражение, которое принимает значение TRUE или FALSE .

    Второй, sql_statement | statement_block - это любая инструкция Transact-SQL или набор инструкций Transact-SQL. Блок операторов определяется с помощью оператора BEGIN ... END .

    Если Boolean_expression при входе в цикл принимает значение FALSE , ни один оператор внутри цикла WHILE выполняться не будет.

    Внутри цикла WHILE вы должны изменить некоторые переменные, чтобы Boolean_expression в некоторых точках возвращал FALSE .В противном случае у вас будет неопределенный цикл.

    Обратите внимание, что если Boolean_expression содержит оператор SELECT , его следует заключить в круглые скобки.

    Чтобы немедленно выйти из текущей итерации цикла, используйте оператор BREAK . Чтобы пропустить текущую итерацию цикла и начать новую, вы используете оператор CONTINUE .

    SQL Server WHILE , пример

    Давайте рассмотрим пример использования оператора SQL Server WHILE , чтобы лучше понять его.

    В следующем примере показано, как использовать оператор WHILE для печати чисел от 1 до 5:

     

    DECLARE @counter INT = 1; ПОКА @counter <= 5 НАЧАТЬ ПЕЧАТЬ @counter; УСТАНОВИТЬ @counter = @counter + 1; КОНЕЦ

    Выход:

     1
    2
    3
    4
    5 

    В этом примере:

    • Сначала мы объявили переменную @counter и установили ее значение равным единице.
    • Затем в условии оператора WHILE мы проверили, меньше ли @counter или равно пяти.Если это не так, мы распечатали @counter и увеличили его значение на единицу. После пяти итераций @counter равно 6, что привело к тому, что условие предложения WHILE оценивается как FALSE , цикл остановился.

    Чтобы узнать, как использовать цикл WHILE для обработки строка за строкой, ознакомьтесь с этим учебным курсом.

    В этом руководстве вы узнали, как использовать инструкцию SQL Server WHILE для повторения выполнения блока инструкций на основе указанного условия.

    .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *