Как организовать бесконечный цикл while в sql server?

Команды IF

Команда IF реализует логику условного выполнения команд программы. С ее помощью можно реализовать конструкции следующего вида:

  • Если оклад находится в пределах от $10 000 до $20 000, начислить премию в размере $1500.
  • Если коллекция содержит более 100 элементов, удалить лишнее.

Команда IF существует в трех формах, представленных в следующей таблице.

Разновидность IF Характеристики
Простейшая форма команды . Условие между и определяет, должна ли выполняться группа команд, находящаяся между и . Если результат проверки условия равен или , то код не выполняется
Реализация логики «или-или». В зависимости от условия между ключевыми словами и выполняется либо код, находящийся между и , либо код между и . В любом случае выполняется только одна из двух групп исполняемых команд
Последняя, и самая сложная, форма выбирает действие из набора взаимоисключающих условий и выполняет соответствующую группу исполняемых команд. Если вы пишете подобную конструкцию в версии Oracle9i Release 1 и выше, подумайте, не заменить ли ее командой выбора

Схема сложного запроса PL/SQL с использованием временных таблиц

Ниже рассмотрена схема получения результирующей таблицы в Oracle Database, используя временные таблицы.

PROCEDURE NameYourProcedure IS

—Объявления переменных
VarName type;
—Объявления курсоров, пример:
CURSOR NameCursor(…) IS
SELECT … FROM …;

—Блок BEGIN … END
BEGIN

—Здесь можно использовать курсор
—Дальше я опишу вариант, который используется вместо VIEW, его можно запустить в открытом курсоре или каком-то цикле (FOR LINE … LOOP)

—«Вместо View использовать временные таблицы, а результат инсертить в промежуточную таблицу»
INSERT INTO NameYourTableResult (
Field1,
Field2,
Field3

FieldN
)
WITH —в этот блок помещаются временные таблицы, которые и заменяют View
TempTable1 as (
—Сложный SQL запрос, результат которого будет храниться в TempTable1 на протяжении всего INSERT INTO
)
TempTable2 as (
—Сложный SQL запрос, в котором мы можем использовать временную таблицу TempTable1 и другие таблицы базы данных
)
TempTable3 as (
—Сложный SQL запрос, в котором мы можем использовать временные таблицы TempTable1, TempTable2 и другие таблицы базы данных
)
—… и так далее, но главное не увлекаться :)

—Основной блок SELECT, из которого результаты пойдут в команду INSERT INTO (количество полей в SELECT равно количеству полей в INSERT)
—В этом запросе SELECT используются временные таблицы TempTable1, TempTable2, TempTable3 и т.д. и другие источники данных
SELECT —Перечень полей
FROM TempTable3, sourceTable1, sourceTable2, sourceTable3
JOIN …
WHERE …;
END;

END NameYourProcedure;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

PROCEDURE NameYourProcedure IS

—Объявленияпеременных

VarName type;

—Объявлениякурсоров,пример

CURSOR NameCursor(…)IS

SELECT…FROM…;

—БлокBEGIN…END

BEGIN

—Здесьможноиспользоватькурсор

—Дальшеяопишувариант,которыйиспользуетсявместоVIEW,егоможнозапуститьвоткрытомкурсореиликаком-тоцикле(FORLINE…LOOP)

—«Вместо View использовать временные таблицы, а результат инсертить в промежуточную таблицу»

INSERT INTO NameYourTableResult(

Field1,

Field2,

Field3

FieldN

)

WITH—вэтотблокпомещаютсявременныетаблицы,которыеизаменяютView

TempTable1 as(

—СложныйSQLзапрос,результаткоторогобудетхранитьсявTempTable1напротяжениивсегоINSERT INTO

)

TempTable2 as(

—СложныйSQLзапрос,вкотороммыможемиспользоватьвременнуютаблицуTempTable1идругиетаблицыбазыданных

)

TempTable3 as(

—СложныйSQLзапрос,вкотороммыможемиспользоватьвременныетаблицыTempTable1,TempTable2идругиетаблицыбазыданных

)

—…итакдалее,ноглавноенеувлекаться)

—ОсновнойблокSELECT,изкоторогорезультатыпойдутвкомандуINSERT INTO(количествополейвSELECTравноколичествуполейвINSERT)

—ВэтомзапросеSELECTиспользуютсявременныетаблицыTempTable1,TempTable2,TempTable3ит.д.идругиеисточникиданных

SELECT—Переченьполей

FROM TempTable3,sourceTable1,sourceTable2,sourceTable3

JOIN…

WHERE…;

END;

ENDNameYourProcedure;

Теперь можно использовать обычный SQL для получения предрассчитанных данных в удобное время (например ночью или утром, для оптимизации использования ресурсов сервера и информационных систем).

Пропущенные выражения в цикле

Также в циклах можно пропускать одно или сразу все выражения, например:

#include <iostream>

int main()
{
int count = 0;
for (; count < 10; )
{
std::cout << count << » «;
++count;
}

return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13

#include <iostream>
 

intmain()

{

intcount=;

for(;count<10;)

{

std::cout<<count<<» «;

++count;

}

return;

}

Результат:

Инициализацию счетчика мы прописали вне тела цикла, а инкремент счетчика — внутри тела цикла. В самом операторе for мы указали только условие. Иногда бывают случаи, когда не требуется объявлять счетчик цикла (потому что у нас он уже есть) или увеличивать его (так как мы увеличиваем его каким-то другим способом).

Хоть это и не часто можно наблюдать, но в операторе for можно вообще ничего не указывать. Стоит отметить, что подобное приведет к бесконечному циклу:

Вышеприведенный пример эквивалентен:

Решение задач

1. Дано положительное число N. Вывести все числа от 0 до N с помощью цикла while.

2. Дано положительное число N. Вывести все числа от N до 0 с помощью цикла while. Пример:

Ввод: N = 10

Вывод: 10

        9

        8

        7

        6

        …

        0

3. Даны два положительных числа K и N (K

4. Даны положительные числа A и B (A > B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Не используя операции умножения и деления, найти длину незанятой части отрезка A (взятие остатка A % B)

5. Даны положительные числа A и B (A > B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Не используя операции умножения и деления, найти количество отрезков B, размещенных на отрезке A (деление нацело A // B)

6. Дано положительное число N. Найти сумму всех четных чисел от 0 до N с помощью цикла while.

7. Даны два положительных числа K и N (K нечетных чисел от K до N с помощью цикла while.

8. Дано положительное число N. Найти факториал числа N. Факториалом числа называется произведение всех чисел от 1 до N. Например, факториал числа 5 равен 5! = 1*2*3*4*5 = 120, 2! = 1*2 = 2, 9! = 1*2*3*4*5*6*7*8*9 = 362880

9. Дано целое число N (> 0). Если оно является степенью числа 3, то вывести YES, если не является — вывести NO.

10. Дано целое число N (> 0). Найти двойной факториал N: N!! = N * (N-2) * (N-4)* …. Для решения этой задачи посмотрите на задачу 2

A simple example: Printing numbers with SQL While loop

Let’s start with a very simple example where we use a SQL While loop to print the first five positive integer
values:

1
2
3
4
5
6
7
8

DECLARE@countINT;

SET@count=1;

WHILE@count<=5

BEGIN

PRINT@count

SET@count=@count+1;

END;

In the script above, we first declare an integer type variable @count and set its value to 5.

Next, we execute a While loop which checks if the value of the @count variable is less than or equals to 5. If the
@count variable has a value less than or equals to 5, the body of the loop executes, and the current value of the
@count variable is printed on the console.

In the next line, the value of the @count variable is incremented by 1. The While loop keeps executing until the value of the @count variable becomes greater than 5. Here is the output:

Best practice

Цикл while в одну строку

Для составных конструкций (таких, где нужен блок с отступом), можно этот отступ убрать, но только если в блоке используются простые операторы. Отделяются они всё также двоеточием.

Например, записи:

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

Вложенные циклы

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

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

Как выйти с помощью break из двух циклов

В случае вложенных циклов, оператор завершает работу только того цикла, внутри которого он был вызван:

В Python не существует конструкций, которая прерывала бы сразу несколько циклов. Но есть как минимум 3 способа, которыми можно реализовать данное поведение:

Способ №1
Используем конструкцию

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

Способ №2
Через создание дополнительного флага:

Внешний цикл был прерван вслед за внутренним. Дело сделано!

Способ №3
Если циклы находятся в функции (как в нашем примере), достаточно просто сделать

Переменные

Переменные — это именованные контейнеры. Они могут содержать информацию (данные) различных видов. В зависимости от того, какую информацию в них можно помещать, они имеют различные типы данных, а чтобы отличать их друг от друга, им присваиваются имена. PL/SQL хранит числа в переменных типа NUMBER, а текст — в переменных типа CHAR или VARCHAR2. Синтаксис объявления переменной в PL/SQL может иметь любую из следующих форм:

имя_переменной тип_данных := выражение_по_умолчанию];
имя_переменной тип_данных DEFAULT выражение_по_умолчанию];

1
2

имя_переменнойтип_данныхNOTNULL=выражение_по_умолчанию;

имя_переменнойтип_данныхNOTNULLDEFAULTвыражение_по_умолчанию;

Имя_переменной — это любой правильный идентификатор PL/SQL. Правильный идентификатор PL/SQL должен:

  • Иметь не более 30 символов в длину и не содержать пробельных символов (собственно пробелов и знаков табуляции).
  • Состоять только из букв, цифр от 0 до 9, символа подчеркивания (_), знака доллара ($) и знака фунта (#).
  • Начинаться с буквы.
  • Не совпадать с зарезервированными словами PL/SQL или SQL, которые имеют специальное значение. Например, именем переменной не может быть слово BEGIN, которое обозначает начало выполняемой секции базового блока PL/SQL.

Тип_данных — это любой допустимый тип данных SQL или PL/SQL. Модификатор NOT NULL требует, чтобы переменная имелазначение. Если он указан, переменной должно быть присвоено значение по умолчанию.

Бесконечный цикл while

Если условие, заданное в цикле while, никогда не становится ложным, цикл while никогда не завершается и превращается в бесконечный цикл while.

Любое ненулевое значение в цикле while указывает на условие “всегда истинное”, тогда как ноль указывает на условие “всегда ложное”. Такой подход полезен, если мы хотим, чтобы наша программа непрерывно работала в цикле без каких-либо помех.

Пример 1:

while(1):  
    print("Hi! we are inside the infinite while loop")

Выход:

Hi! we are inside the infinite while loop
Hi! we are inside the infinite while loop

Пример 2:

var = 1  
while(var != 2):  
    i = int(input("Enter the number:"))  
    print("Entered value is %d"%(i))  

Выход:

Enter the number:10
Entered value is 10
Enter the number:10
Entered value is 10
Enter the number:10
Entered value is 10
Infinite time

Примеры:

Некоторые примеры динамического SQL

Oracle PL/SQL

DECLARE
sql_stmt VARCHAR2(200);
plsql_block VARCHAR2(500);
emp_id NUMBER(4) := 7566;
salary NUMBER(7,2);
dept_id NUMBER(2) := 50;
dept_name VARCHAR2(14) := ‘PERSONNEL’;
location VARCHAR2(13) := ‘DALLAS’;
emp_rec emp%ROWTYPE;
BEGIN
—EXECUTE IMMEDIATE c SQL предложением
EXECUTE IMMEDIATE ‘CREATE TABLE bonus (id NUMBER, amt NUMBER)’;

—присвоим sql_stmt строковое SQL предложение с заполнителями :1, :2, :3
sql_stmt := ‘INSERT INTO dept VALUES (:1, :2, :3)’;

—запустим EXECUTE IMMEDIATE с sql_stmt используя аргументы связывания dept_id, dept_name, location
EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location;

—присвоим sql_stmt SQL предложение с заполнителем :id
sql_stmt := ‘SELECT * FROM emp WHERE empno = :id’;

—запустим EXECUTE IMMEDIATE с sql_stmt используя аргумент связывания emp_id и сохраним результат в emp_rec
EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;

—присвоим plsql_block запуск анонимного блока с подпрограммой raise_salary пакета emp_pkg с заполнителями :id, :amt
plsql_block := ‘BEGIN emp_pkg.raise_salary(:id, :amt); END;’;

—запустим EXECUTE IMMEDIATE с plsql_block используя аргументы связывания :id, :amt
EXECUTE IMMEDIATE plsql_block USING 7788, 500;

—присвоим sql_stmt SQL предложение с заполнителем :1, :2
sql_stmt := ‘UPDATE emp SET sal = 2000 WHERE empno = :1 RETURNING sal INTO :2’;

—запустим EXECUTE IMMEDIATE с sql_stmt используя аргументы связывания emp_id, salary
EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;

—EXECUTE IMMEDIATE c SQL предложение с заполнителем :num и аргументом связывания dept_id
EXECUTE IMMEDIATE ‘DELETE FROM dept WHERE deptno = :num’ USING dept_id;

—EXECUTE IMMEDIATE c SQL предложением
EXECUTE IMMEDIATE ‘ALTER SESSION SET SQL_TRACE TRUE’;
END;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

DECLARE

sql_stmtVARCHAR2(200);

plsql_blockVARCHAR2(500);

emp_idNUMBER(4):=7566;

salaryNUMBER(7,2);

dept_idNUMBER(2):=50;

dept_nameVARCHAR2(14):=’PERSONNEL’;

locationVARCHAR2(13):=’DALLAS’;

emp_recemp%ROWTYPE;
BEGIN
—EXECUTE IMMEDIATE c SQL предложением

EXECUTEIMMEDIATE’CREATE TABLE bonus (id NUMBER, amt NUMBER)’;
 
—присвоим sql_stmt строковое SQL предложение с заполнителями :1, :2, :3

sql_stmt:=’INSERT INTO dept VALUES (:1, :2, :3)’;
 
—запустим EXECUTE IMMEDIATE с sql_stmt используя аргументы связывания dept_id, dept_name, location

EXECUTEIMMEDIATEsql_stmtUSINGdept_id,dept_name,location;
 
—присвоим sql_stmt SQL предложение с заполнителем :id

sql_stmt:=’SELECT * FROM emp WHERE empno = :id’;
 
—запустим EXECUTE IMMEDIATE с sql_stmt используя аргумент связывания emp_id и сохраним результат в emp_rec

EXECUTEIMMEDIATEsql_stmtINTOemp_recUSINGemp_id;
 
—присвоим plsql_block запуск анонимного блока с подпрограммой raise_salary пакета emp_pkg с заполнителями :id, :amt

plsql_block:=’BEGIN emp_pkg.raise_salary(:id, :amt); END;’;
 
—запустим EXECUTE IMMEDIATE с plsql_block используя аргументы связывания :id, :amt  

EXECUTEIMMEDIATEplsql_blockUSING7788,500;
 
—присвоим sql_stmt SQL предложение с заполнителем :1, :2

sql_stmt:=’UPDATE emp SET sal = 2000 WHERE empno = :1 RETURNING sal INTO :2′;
 
—запустим EXECUTE IMMEDIATE с sql_stmt используя аргументы связывания emp_id, salary

EXECUTEIMMEDIATEsql_stmtUSINGemp_idRETURNINGINTOsalary;
 
—EXECUTE IMMEDIATE c SQL предложение с заполнителем :num и аргументом связывания dept_id

EXECUTEIMMEDIATE’DELETE FROM dept WHERE deptno = :num’USINGdept_id;
 
—EXECUTE IMMEDIATE c SQL предложением   

EXECUTEIMMEDIATE’ALTER SESSION SET SQL_TRACE TRUE’;

END;

Пример процедуры динамического SQL, которая принимает имя таблицы и предложение WHERE

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

Oracle PL/SQL

CREATE OR REPLACE PROCEDURE delete_rows (
table_name IN VARCHAR2,
condition IN VARCHAR2 DEFAULT NULL) AS
where_clause VARCHAR2(100) := ‘ WHERE ‘ || condition;
BEGIN
IF condition IS NULL THEN where_clause := NULL; END IF;
EXECUTE IMMEDIATE ‘DELETE FROM ‘ || table_name || where_clause;
END;

1
2
3
4
5
6
7
8

CREATEORREPLACEPROCEDUREdelete_rows(

table_nameINVARCHAR2,

conditionINVARCHAR2DEFAULTNULL)AS

where_clauseVARCHAR2(100):=’ WHERE ‘||condition;
BEGIN

IFconditionISNULLTHENwhere_clause:=NULL;ENDIF;

EXECUTEIMMEDIATE’DELETE FROM ‘||table_name||where_clause;

END;

Что дальше

  • Когда вам нужно принять решение об обработке данных, определите, где вы можете столкнуться с использованием курсоров. Это может иметь место в вашем приложении или в операционных процессах. Существует много способов решить задачу. Использование курсора может оказаться разумной альтернативой в некоторых случаях. Решать вам.
  • Если вы сталкиваетесь в проблемами при другом способе кодирования, и необходимо сделать что-то быстро, использование курсора может быть надежной альтернативой. Она может привести к более продолжительной обработке данных, но время написания кода может стать значительно быстрей. Если вам требуется одноразовый процесс или процесс, выполняемый в ночное время, это может помочь.
  • Если в вашей среде избегают курсоров, выберите другое надежное решение. Просто убедитесь, что этот процесс не вызовет других проблем. Например, если используется курсор и обрабатываются миллионы строк, не приведет ли это к удалению всех данных из кеша и не спровоцирует ли дальнейшие конфликты? Или при большом наборе данных не будут ли данные сброшены на диск или записаны во временную директорию?
  • Оценивая подход на основе курсора по сравнению с другими альтернативами, проведите честное сравнение методов с точки зрения времени, возможности конфликтов и необходимых ресурсов. Надеюсь, что эти факторы приведут вас к правильному способу.

Вложенные команды IF

Команды IF можно вкладывать друг в друга. В следующем примере представлены команды IF с несколькими уровнями вложенности:

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

И если вы собираетесь применить команды более чем с тремя уровнями вложения, подумайте, нельзя ли пересмотреть логику программы и реализовать требования более простым способом. Если такового не найдется, подумайте о создании одного или нескольких локальных модулей, скрывающих внутренние команды . Главное преимущество вложенных структур заключается в том, что они позволяют отложить проверку внутренних условий. Условие внутренней команды проверяется только в том случае, если значение выражения во внешнем условии равно . Таким образом, очевидной причиной вложения команд может быть проверка внутреннего условия только при истинности другого. Например, код начисления премий можно было бы записать так: 

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

Немного информатики

Как было отмечено выше,

Напишем на псевдокоде классическую схему:

Конструкция начинает свою работу с проверки условия, и, если оно истинно, запускается цикл. На каждой новой итерации (единичный проход по циклу) условие продолжения проверяется вновь. Таким образом, последовательность инструкций будет исполняться до тех пор, пока это условие, наконец, не окажется ложным.

Циклы, как механизм программирования, нужны, главным образом, для упрощения написания кода. Вполне очевидно, что создавать программу, выполняющую определённую операцию для каждой точки 4К дисплея в отсутствии циклов — это вручную повторять описание нужной команды 4096*2160 раз. Много? Безусловно.

Применение в этой задаче всего одного цикла позволит сократить длину кода, как минимум, на 6 порядков. А если представить, что ту же самую программу нужно переписать для 8К монитора, то, вместо изменения всего одной инструкции в счетчике цикла, вам придётся дописывать ещё пару десятков миллионов строк кода, что является попросту недопустимым по своей величине и трудозатратам объёмом.

Польза циклов ясна и очевидна. Обладая мощной выразительностью и ёмкой натурой, они, без сомнений, являются одним из фундаментальных конструктов высокоуровневого программирования. Каждому разработчику необходимо знать и понимать принципы их работы.

TOAD

Инструментальное средство TOAD (Tool for Oracle Application Development) является одним из наиболее популярных средств разработки серверных приложений Oracle. TOAD в процессе работы позволяет устанавливать несколько соединений с БД. Доступ к набору инструментальных средств, используемых при разработке и отладке серверных приложений и схем баз данных осуществляется, преимущественно, с помощью пункта главного меню Database.

  • Database -> Schema Browser – открывает окно браузера, с помощью которого осуществляется доступ к информации об объектах схем, видимых в текущем соединении.
  • Database -> SQL Editor – используется для написания и выполнения команд и скриптов SQL;
  • Database -> Procedure Editor – предоставляет пользователю инструментальные средства для разработки блоков PL/SQL;
  • Database -> SQL Modeller – поддерживает процесс визуального составления SQL-запросов;
  • Database -> Export -> … – предоставляет пользователю возможность выгрузки данных из БД в виде скриптов SQL;
  • Database -> Import -> … – импортирует данные в БД;
  • Database -> Commit – осуществляет фиксацию транзакции в текущем соединении;
  • Database -> Rollback – осуществляет откат транзакции в текущем соединении.

Термины в исключениях:

  • Раздел исключений — необязательный раздел блока PL/SQL (анонимного блока, процедуры, функции, триггера или инициализационного раздела пакета), содержащий один или несколько обработчиков исключений. Структура раздела исключений очень похожа на структуру команды CASE.
  • Инициировать исключение — значит остановить выполнение текущего блока PL/SQL, оповещая исполняемое ядро об ошибке. Исключение может инициировать либо Oracle, либо ваш собственный программный код при помощи команды RAISE или процедуры RAISE_APPLICATION_ERROR.
  • Обработать исключение — значит перехватить ошибку, передав управление обработчику исключения. Написанный программистом обработчик может содержать код, который в ответ на исключение выполняет определенные действия (например, записывает информацию об ошибке в журнал, выводит сообщение для пользователя или передает исключение во внешний блок).
  • Область действия — часть кода (конкретный блок или весь раздел), в котором может инициироваться исключение, а также часть кода, инициируемые исключения которого могут перехватываться и обрабатываться соответствующим разделом исключений.
  • Передача исключения — процесс передачи исключения во внешний блок, если в текущем блоке это исключение не обработано.
  • Необработанное исключение — исключение, которое передается без обработки из «самого внешнего» блока PL/SQL. После этого управление передается исполнительной среде, которая уже сама определяет, как отреагировать на исключение (выполнить откат транзакции, вывести сообщение об ошибке, проигнорировать ее и т. д.).
  • Анонимное исключение — исключение, с которым связан код ошибки и описание. Такое исключение не имеет имени, которое можно было бы использовать в команде RAISE или секции WHEN обработчика исключений.
  • Именованное исключение — исключение, которому имя присвоено либо Oracle (в одном из встроенных пакетов), либо разработчиком. В частности, для этой цели можно использовать директиву компилятора EXCEPTION_INIT (в таком случае имя можно будет применять и для инициирования, и для обработки исключения).

Список литературы

  • Кристофер Аллен – ORACLE PL/SQL «Как писать мощные и гибкие программы на PL/SQL»
  • Фейерштейн С., Прибыл Б. — «Oracle PL/SQL. Для профессионалов.» 6-е изд. — СПб.: Питер, 2015. — 1024 с.

The CONTINUE and BREAK statements

The CONTINUE statement is used to shift the control back to the start of a while loop in SQL. The BREAK statement is used to terminate the loop.

The following script shows how to use the CONTINUE statement inside a while loop to print the first five positive
even integers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

DECLARE@countINT;

DECLARE@modINT;

SET@count=1;

WHILE@count<=10

BEGIN

set@mod=@count%2

IF@mod=1

BEGIN

SET@count=@count+1;

CONTINUE

END

PRINT@count

SET@count=@count+1;

END;

In the script above, the while loop executes until the value of the @count variable remains less than or equal to
10. The initial value of the @count variable is 1.

In the body of the loop, the value of the remainder of the @count divided by 2 is stored in the @mod variable. If
the value of the @count variable is odd, the remainder will be 1, and if the remainder is 0, the CONTINUE statement
is used to shift the control back to the start of the while loop and the value of the @count variable is not
printed.

Otherwise, the value of the @count variable is printed on the console. Here is the output of the above script:

The following example demonstrates the use of a BREAK statement. The while loop in the following script will
terminate after printing the first five integers:

1
2
3
4
5
6
7
8
9
10
11
12

DECLARE@countINT;

SET@count=1;

WHILE@count<=10

BEGIN

IF@count>5

BEGIN

BREAK

END

PRINT@count

SET@count=@count+1;

END;

Используем курсор и цикл в процедуре

Перейдем сразу к делу и напишем процедуру (my_proc_test_all), код я как всегда прокомментировал:

   
   CREATE PROCEDURE .
   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 сработала все три раза, а мы всего лишь один раз запустили дополнительную процедуру.

Второй вариант.

Таблица базы данных

База данных чаще всего содержит одну или несколько таблиц.
Каждая таблица идентифицируется по имени (например, «клиенты» или «заказы»).
Таблицы содержат записи (строки) с данными.

В этом уроке мы будем использовать хорошо известный образец базы данных Northwind (входит в MS Access и MS SQL Server).

Ниже приведен выбор из таблицы «клиенты»:

CustomerID CustomerName ContactName Address City PostalCode Country
1 Alfreds Futterkiste Maria Anders Obere Str. 57 Berlin 12209 Germany
2 Ana Trujillo Emparedados y helados Ana Trujillo Avda. de la Constitución 2222 México D.F. 05021 Mexico
3 Antonio Moreno Taquería Antonio Moreno Mataderos 2312 México D.F. 05023 Mexico
4 Around the Horn Thomas Hardy 120 Hanover Sq. London WA1 1DP UK
5 Berglunds snabbköp Christina Berglund Berguvsvägen 8 Luleå S-958 22 Sweden

Приведенная выше таблица содержит пять записей (по одной для каждого клиента)
и семь столбцов (CustomerID, CustomerName, ContactName, Address, City, PostalCode и Country).

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: