Опубликован: 11.03.2009 | Доступ: свободный | Студентов: 2469 / 426 | Оценка: 4.22 / 4.22 | Длительность: 11:41:00
Лекция 9:

Внутренний язык СУБД. Сравнительные характеристики T-SQL и PL/SQL

< Лекция 8 || Лекция 9: 12 || Лекция 10 >
Аннотация: Лекция посвящена теме внутреннего языка СУБД. В теоретической части рассказывается об основных характеристиках PL/SQL и T-SQL, структуре блока PL/SQL, об основных объектах (триггерах, хранимых процедурах и функциях). А также, рассматриваются практические задания по теме.

Введение

Практически каждая СУБД имеет в своем составе процедурное расширение языка SQL. Эти языки используются для реализации бизнес-логики и дополнительных проверок целостности на уровне сервера. Программные модули, написанные на этих языках, хранятся в СУБД и выполняются специальным компонентом непосредственно в ядре СУБД. Синтаксис таких языков разработан для максимально простой и удобной интеграции с SQL. Модули процедурного расширения SQL могут быть одного из следующих типов

  1. Хранимые процедуры, пакеты, функции
  2. Триггеры
  3. Безымянные блоки

Oracle. Процедурное расширение - PL/SQL. Синтаксис похож на ADA. Помимо СУБД, входит в другие продукты Oracle, например Oracle Developer. Является наиболее мощным из процедурных языков основных СУБД.

SQL Server. Процедурное расширение - Transact-SQL (T-SQL). Обладает основными возможностями. До версии 2005 отсутствовала обработка исключений.

Основные характеристики PL/SQL и T-SQL

  • Полный диапазон типов данных
  • Явно определяемая структура кода - блоки данных, процедуры и т.д.
  • Операторы управления потоком команд - условные, циклы и т.д.
  • Обработчики исключений
  • Повторно используемые именованные блоки кода, такие как функции, процедуры, пакеты (только в PL/SQL)
  • Тесная интеграция с SQL - непосредственный вызов команд SQL из процедурного кода

Блок PL/SQL. Структура

Вызов из sqlplus:

call dbms_output.put_line('aaa')
exec dbms_output.put_line('aaa')

Структура блока plsql

declare
    i number;
    d date;
begin
    i := 0;

    select count(*) into i from all_users;

    if i > 10 then
        dbms_output.put_line('> 10');
    else
        dbms_output.put_line('<= 10');
    end if;

    begin
        select sysdate into d from dual;
    exception
        when no_data_found then
            d := null;
            raise;
    end;
end;

Основные элементы plsql

Комментарии
/*
многострочные 
комментарии
*/
Идентификаторы
declare
    LongName number;
begin
    longname := 10;
    dbms_output.put_line(LONGNAME);
end;

declare
    "LongName" number;
begin
    longname := 10;
    dbms_output.put_line(LONGNAME);
end;

declare 
    n_$# number;
begin
    n_$# := 10;
end;
Логический тип
declare
    b boolean;
begin
    b := true;
-- error
--    dbms_output.put_line(b);

    dbms_output.put_line(case b when true then 1 else 0 end);

    if b then
        dbms_output.put_line(1);
    else
        dbms_output.put_line(0);
    end if;        
end;
Декларации
declare
    n1 number;
    n2 number := 10;
    n3 number default 10;
    n4 number not null := 30;
begin
    dbms_output.put_line(nvl(n1, -100));
    dbms_output.put_line(n2);
    dbms_output.put_line(n3);
    dbms_output.put_line(n4);
end;

declare
    n test.i%type;
    r test%rowtype;
begin
    n := 10;
    dbms_output.put_line(n);

    select * into r from test where i = 1;
    dbms_output.put_line(r.i);
    dbms_output.put_line(r.s);
end;

-- видимость переменных
declare 
    a number := 10;
    b number := 20;
begin
    dbms_output.put_line(a);
    dbms_output.put_line(b);

    declare
        a number;
        c number;
    begin
        a := 30;
        c := 40;
        dbms_output.put_line('---->'||a);
        dbms_output.put_line('---->'||b);
        dbms_output.put_line('---->'||c);
    end;

    dbms_output.put_line(a);
    dbms_output.put_line(b);
end;
Именованные блоки
<<my_block>>
declare 
    a number := 10;
    b number := 20;
begin
    dbms_output.put_line(a);
    dbms_output.put_line(b);

    declare
        a number;
        c number;
    begin
        a := 30;
        c := 40;
        dbms_output.put_line('---->'||my_block.a);
        dbms_output.put_line('---->'||a);
        dbms_output.put_line('---->'||b);
        dbms_output.put_line('---->'||c);
    end;

    dbms_output.put_line(a);
    dbms_output.put_line(b);
end;

<<my_block1>>
declare 
    a number := 10;
begin
    dbms_output.put_line('my_block1 '||a);

    <<my_block2>>
    declare
        a number := 20;
    begin
        dbms_output.put_line('my_block2 '||my_block1.a);
        dbms_output.put_line('my_block2 '||a);

        <<my_block3>>
        declare
            a number := 30;
        begin
            dbms_output.put_line('my_block3 '||my_block1.a);
            dbms_output.put_line('my_block3 '||my_block2.a);
            dbms_output.put_line('my_block3 '||a);
        end;
    end;

    dbms_output.put_line('my_block1 '||a);
end;
Управляющие конструкции
declare
    n number;
begin
    n := 10;

    if n > 10 then
        n := 20;
        dbms_output.put_line(n);
    else
        n := 30;
        dbms_output.put_line(n);
    end if;

    if n > 10 then
        n := 20;
        dbms_output.put_line(n);
    end if;

    if n > 10 then
        n := 20;
        dbms_output.put_line(n);
    elsif n > 5 then
        n := 30;
        dbms_output.put_line(n);
    else
        n := 40;
        dbms_output.put_line(n);
    end if;

    case n
        when 10 then 
            n := 100;
            dbms_output.put_line(n);
        when 12 then 
            n := 200;
            dbms_output.put_line(n);
        else
            n := 300;
            dbms_output.put_line(n);
    end case;

    case 
        when n = 10 then 
            n := 100;
            dbms_output.put_line(n);
        when n = 12 then 
            n := 200;
            dbms_output.put_line(n);
        else
            n := 300;
            dbms_output.put_line(n);
    end case;
end;

declare
    n number := 10;
begin
    case n
        when 1 then
            dbms_output.put_line('1');
        when 2 then
            dbms_output.put_line('1');
    end case;
exception
    when case_not_found then
        dbms_output.put_line('case not found');
end;

declare
    n number;
begin
    n := 1;

    loop
        dbms_output.put_line(n);
        n := n+1;
        exit when n > 10;
    end loop;
end;

declare
    n number;
begin
    n := 1;

    loop
        dbms_output.put_line(n);
        n := n+1;
        if n > 10 then
            exit;
        end if;
    end loop;
end;

declare
    n number;
begin
    n := 1;

    while n <= 10 loop
        dbms_output.put_line(n);
        n := n+1;
    end loop;
end;

declare
    n number;
begin
    for n in 1..10 loop
        dbms_output.put_line(n);
    end loop;
end;

declare
    n number;
begin
    for n in reverse 1..10 loop
        dbms_output.put_line(n);
    end loop;
end;
< Лекция 8 || Лекция 9: 12 || Лекция 10 >
Александра Каева
Александра Каева
Светлана Токаревская
Светлана Токаревская

Добрый день! Скажите пожалуйста, так и задумано, что в каждой лекции приложен один и тот же приктикум?

Алексей Мендрин
Алексей Мендрин
Украина
Уалихан Джумадилов
Уалихан Джумадилов
Россия