Главная страница
Навигация по странице:

  • Оператор цикла WHILE

  • Оператор цикла REPEAT

  • Оператор цикла LOOP

  • практическая работа. Практическая работа - для слияния. Практическая работа 1 sql создание базы данных и таблиц Цель


    Скачать 3.41 Mb.
    НазваниеПрактическая работа 1 sql создание базы данных и таблиц Цель
    Анкорпрактическая работа
    Дата14.02.2023
    Размер3.41 Mb.
    Формат файлаdocx
    Имя файлаПрактическая работа - для слияния.docx
    ТипПрактическая работа
    #936408
    страница18 из 18
    1   ...   10   11   12   13   14   15   16   17   18





    Практическая работа № 18

    SQL - Хранимые процедуры. Часть 4.


    Цель: научиться работать с хранимыми процедурами

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

    Оператор цикла WHILE

    Сначала синтаксис:
    WHILE условие DO

    запрос

    END WHILE

    Запрос будет выполняться до тех пор, пока условие истинно. Давайте посмотрим на примере, как это работает. Предположим, мы хотим знать названия, авторов и количество книг, которые поступили в различные поставки. Интересующая нас информация хранится в двух таблицах - Журнал Поставок (magazine_incoming) и Товар (products). Давайте напишим интересующий нас запрос:
    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product;

     
    А что, если нам необходимо, чтобы результат выводился не в одной таблице, а по каждой поставке отдельно? Конечно, можно написать 3 разных запроса, добавив в каждый еще одно условие:
    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product AND magazine_incoming.id_incoming=1;
    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product AND magazine_incoming.id_incoming=2;
    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product AND magazine_incoming.id_incoming=3;

    Но гораздо короче сделать это можно с помощью цикла WHILE:
    DECLARE i INT DEFAULT 3;

    WHILE i>0 DO

    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product AND magazine_incoming.id_incoming=i;

    SET i=i-1;

    END WHILE;

    Т.е. мы ввели переменную i, по умолчанию равную 3, сервер выполнит запрос с id поставки равным 3, затем уменьшит i на единицу (SET i=i-1), убедится, что новое значение переменной i положительно (i>0) и снова выполнит запрос, но уже с новым значением id поставки равным 2. Так будет происходить, пока переменная i не получит значение 0, условие станет ложным, и цикл закончит свою работу.

    Чтобы убедиться в работоспособности цикла создадим хранимую процедуру books и поместим в нее цикл:
    DELIMITER //

    CREATE PROCEDURE books ()

    begin

    DECLARE i INT DEFAULT 3;

    WHILE i>0 DO

    SELECT magazine_incoming.id_incoming, products.name, products.author,

    magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product

    AND magazine_incoming.id_incoming=i;

    SET i=i-1;

    END WHILE;

    end

    //

     

    Теперь вызовем процедуру:
    CALL books ()//

     

    Теперь у нас 3 отдельные таблицы (по каждой поставке). Согласитесь, что код с циклом гораздо короче трех отдельных запросов. Но в нашей процедуре есть одно неудобство, мы объявили количество выводимых таблиц значением по умолчанию (DEFAULT 3), и нам придется с каждой новой поставкой менять это значение, а значит код процедуры. Гораздо удобнее сделать это число входным параметром. Давайте перепишем нашу процедуру, добавив входной параметр num, и, учитывая, что он не должен быть равен 0:
    CREATE PROCEDURE books (IN num INT)

    begin

    DECLARE i INT DEFAULT 0;

    IF (num>0) THEN

    WHILE i < num DO

    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product AND magazine_incoming.id_incoming=i;

    SET i=i+1;

    END WHILE;

    ELSE

    SELECT 'Задайте правильный параметр';

    END IF;

    end

    //

    CALL books (0)//

     
    Убедитесь, что с другими параметрами, мы по-прежнему получаем таблицы по каждой поставке. У нашего цикла есть еще один недостаток - если случайно задать слишком большое входное значение, то мы получим псевдобесконечный цикл, который загрузит сервер бесполезной работой. Такие ситуации предотвращаются с помощью снабжения цикла меткой и использования оператора LEAVE, обозначающего досрочный выход из цикла.
    CREATE PROCEDURE books (IN num INT)

    begin

    DECLARE i INT DEFAULT 0;

    IF (num>0) THEN

    wet : WHILE i < num DO

    IF (i>10) THEN LEAVE wet;

    ENF IF;

    SELECT magazine_incoming.id_incoming, products.name, products.author, magazine_incoming.quantity

    FROM magazine_incoming, products

    WHERE magazine_incoming.id_product=products.id_product AND magazine_incoming.id_incoming=i;

    SET i=i+1;

    END WHILE wet;

    ELSE

    SELECT 'Задайте правильный параметр';

    END IF;

    end

    //

    Итак, мы снабдили наш цикл меткой wet вначале (wet:) и в конце, а также добавили еще одно условие - если входной параметр больше 10 (число 10 взято произвольно), то цикл с меткой wet следует закончить (IF (i>10) THEN LEAVE wet). Таким образом, если мы случайно вызовем процедуру с большим значением num, наш цикл прервется после 10 итераций (итерация - один проход цикла).

    Циклы в MySQL, так же как и операторы ветвления, на практике в web-приложениях почти не используются. Поэтому для двух других видов циклов приведем лишь синтаксис и отличия. Вряд ли вам доведется их использовать, но знать об их существовании все-таки надо.

    Оператор цикла REPEAT

    Условие цикла проверяется не в начале, как в цикле WHILE, а в конце, т.е. хотя бы один раз, но цикл выполняется. Сам же цикл выполняется, пока условие ложно. Синтаксис следующий:
    REPEAT

    запрос

    UNTIL условие

    END REPEAT

    Оператор цикла LOOP

    Этот цикл вообще не имеет условий, поэтому обязательно должен иметь оператор LEAVE. Синтаксис следующий:
    LOOP

    запрос

    END LOOP

    На этом мы заканчиваем уроки посвященные SQL.

    1   ...   10   11   12   13   14   15   16   17   18


    написать администратору сайта