Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Лабораторная работа № 4. Триггеры баз данных



Цель работы – изучение предназначения и особенностей создания триггеров баз данных. Определение особенностей данных объектов баз данных от хранимых процедур и функций.

 

· Теоретические сведения

Триггер базы данных – это хранимая процедура, которую можно связать с некоторой таблицей. Когда приложение выполняет SQL оператор DML над таблицей, удовлетворяющей условиям, указанным в триггере, ORACLE автоматически активизирует или выполняет триггер. Таким образом, триггеры можно использовать для настройки реакции ORACLE на различные события приложения. Вне зависимости от типа триггера все триггеры создаются одинаково. Общий синтаксис создания, таков:

 

сreate [or replace] trigger имя_триггера

{before | after | instead of} активизирующее_событие

on имя_таблицы

[for each row]

тело_триггера

 

Здесь активизирующее_событие, указывает событие активации триггера (далее указывается конкретная таблица или представление).

Например, следующий триггер автоматически регистрирует изменения, вносимые в таблицу parts:

create or replace trigger parts_log

after insert or update or delete on parts

declare

stmt_type char(1);

begin

if inserting then

stmt_type: =’I’;

elsif updating then

stmt_type: =’U’;

else

stmt_type: =’D’;

end if;

insert into part_change_log

values(stmt_type, USER);

end parts_log;

 

Как видно из выше приведенного примера, описание триггера содержит однозначно определяемые части:

- Список операторов, активизирующих триггер, который включает insert, update и/или delete. Триггер может быть связан с одной и только с одной таблицей

- Триггер может быть активизирован до (before) или после (after) выполнения оператора триггера в зависимости от логики конкретного приложения.

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

 

create or replace trigger parts_log

before insert or update or delete on parts

for each row

declare

stmt_type char(1);

begin

if inserting then

stmt_type: =’I’;

elsif updating then

stmt_type: =’U’;

else

stmt_type: =’D’;

end if;

insert into part_change_log

values (: new.id, : old.id, : new.unit_price, : old. unit_price, : new.description, : old. description, stmt_type, USER, TO_CHAR (SYSDATE, ’DD-MON-YYYY’));

end parts_log;

 

Из рассмотренных выше примеров видно, что в PL/SQL имеются следующие уникальные языковые конструкции для триггеров баз данных:

- предикаты inserting, updating, deleting могут использоваться в операторах условного перехода в теле триггера.

- значения корреляции позволяют с помощью строковых триггеров обращаться к новым и старым значениям полей текущей строки. Когда оператором триггера является insert все старые значения полей являются null –значениями. Аналогично, когда оператором триггера является delete все новые значения являются соответственно null – значениями.

В предыдущих версиях ORACLE обновляемыми были лишь те представления, которые соответствовали основному правилу обновления представлений. В 8-й версии ORACLE любое представление, для которого создан триггер типа instead of . Детальное описание триггеров instead of приведено в [3].

 

· Варианты заданий

1 Написать триггер настроенный на операцию добавления записей в таблицу сотрудников, с фиксацией идентификатора строки и даты выполненного обновления во вспомогательной таблице базы данных.

 

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

 

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

 

4 Создать триггер, настроенный на ввод новых строк в таблицу с описанием сотрудников. Реакцией на добавление должна быть проверка количества работающих сотрудников в заданном отделении и занесение (путем разового обновления данных соответствующего столбца ) этого количества с учетом нового сотрудника во вспомогательную таблицу. В случае превышения вычисленного значения 5 в строку с данным отделением во вспомогательной таблице следует добавить некоторое информирующее сообщение.

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

 

· Контрольные вопросы

1 Что такое триггер?

2 Чем отличаются триггеры от хранимых процедур и функций

3 Какие типы триггеров вы знаете?

 

 

Лабораторная работа № 5. Динамический SQL

Цель работы – ознакомление с таким объектом баз данных как модули, а также с системными модулями DBMS_OUTPUT, предназначенном для отладки приложений PL/SQL и DBMS_SQL, предназначенном для написания процедур динамической обработки SQL – операторов.

 

· Теоретические сведения

Перед тем как рассмотреть использование модуля DBMS_SQL для организации “динамических” процедур следует рассмотреть такие объекты баз данных как модули.

 

Модули

Модуль (package) – это группа процедур, функций и других конструкций, хранимых вместе в базе данных как одна единица. Модули особенно полезны для компоновки нескольких процедур и функций, имеющих отношение к конкретному приложению баз данных.

Модуль состоит из двух частей: описания и тела.

- Описание модуля определяет интерфейс связи с этим модулем. В описании модуля объявляются все переменные и именованные константы, курсоры, процедуры, функции и другие конструкции модуля, которые необходимо сделать доступными для программ, внешних по отношению к этому модулю. Другими словами, всё объявленное в описании модуля является общим.

- В теле модуля (package body) определяются все общие процедуры и функции, объявленные в описании модуля. Кроме того, в тело модуля могут включаться определения других конструкций, не указанных в его описании. Такие конструкции модуля являются частными, т. е. доступными только для программ внутри модуля.

Ниже приведен пример определения описания модуля и его тела:

 

сreate or replace package part_mgmt is

--глобальная переменная

сurrent_part parts %rowtype;

--процедуры и функции

--insert_part вводит новый элемент ассортимента в таблицу parts

--update_part_unitprice обновляет цену элемента ассортимента

--delete_part удаляет элемент ассортимента

---------------------------------------------------------------------------------

procedure insert_part (part_record parts %rowtype);

procedure update_part_unitprice (part_id in integer, new_price in number);

procedure delete_part (part_id in integer);

end part_mgmt;

 

сreate or replace package body part_mgmt is

procedure insert_part (part_record parts %rowtype) is

dup_primary_key exception;

begin

insert into parts

values (part_record.id, part_record.unitprice, part_record.description);

exception

when dup_ primary_key then

raise_application_error (-20001, ’Дубликат ID’);

when others then

raise_application_error (-20002, ’Неопределенная ошибка’);

end insert_part;

------------------------------------------------------------------------------------

определение других процедур и функций модуля

end part_mgmt;

 

Обращение к процедурам и функциям модуля происходит посредством уточняющей записи через точку.

 

Модуль DBMS_OUTPUT

С помощью процедур модуля DBMS_OUTPUT реализованы две базовые операции: GET и PUT. Операция PUT берет свои аргументы и помещает во внутренний буфер для хранения. Операция GET считывает этот буфер и возвращает его содержимое процедуре в качестве аргумента. Размер буфера устанавливается с помощью процедуры ENABLE.

Выполнение операции PUT обеспечивается процедурами PUT, PUT_LINE и NEW_LINE, а выполнение операции GET – процедурами GET_LINE и GET_LINES. Управляют буфером процедуры ENABLE и DISABLE.

Процедуры PUT и PUT_LINE вызываются следующим образом:

procedure PUT (a varchar2);

procedure PUT (a number);

procedure PUT (a date);

 

procedure PUT_LINE (a varchar2);

procedure PUT_LINE (a number);

procedure PUT_LINE (a date);

 

Данные процедуры переопределяются типом параметра.

Буфер организован в виде строк, каждая из которых может состоять не более чем из 255 байт. PUT_LINE добавляет к аргументу символ новой строки, сообщая о конце строки; PUT же этого не делает. Вызов PUT_LINE аналогичен вызову PUT с последующим вызовом NEW_LINE.

Процедура GET_LINE вызывается следующим образом:

procedure GET_LINE (line out varchar2, status out integer);

где line представляет собой последовательность символов, из которых состоит одна строка буфера, а status указывает на то, успешно или нет была считана эта строка. Максимальная длина строки – 255 байт. Если строка считана, то в переменной status находится 0, если в буфере больше нет строк для считывания, то в status – 1.

Аргументом процедуры GET_LINES является индексная таблица. Тип таблицы и вызов данной процедуры выглядят следующим образом:

type CHARARR is table of varchar2(255) index by binary integer;

procedure GET_LINES (lines out chararr, numlines in out integer);

где numlines – число запрошенных строк, на входе в GET_LINES указывается число запрошенных строк, на выходе – число фактически возвращаемых строк.

Тип CHARARR определен в модуле DBMS_OUTPUT, поэтому если GET_LINES вызывается явным образом, нужно объявлять переменную с типом DBMS_OUTPUT.CHARARR. Например:

 

declare

v_Data DBMS_OUTPUT.CHARARR;

v_NumLines number;

begin

DBMS_OUTPUT.ENABLE (1000000);

DBMS_OUTPUT.PUT_LINE (‘Line one’);

DBMS_OUTPUT.PUT_LINE (‘Line two’);

DBMS_OUTPUT.PUT_LINE (‘Line three’);

v_NumLines: =3;

DBMS_OUTPUT.GET_LINES( v_Data, v_NumLines);

for v_Counter in 1..3 v_NumLines loop

insert into temp_table (char_col)

values (v_Data(v_Counter));

end loop;

end;

 

Процедура ENABLE задает размер буфера в байтах, по умолчанию задается размер 20000 байт, а максимальный размер – 1000000 байт. Если объявлена процедура DISABLE, то содержимое буфера уничтожается и последующие вызовы PUT и PUT_LINE бесполезны.

По существу, модуль DBMS_OUTPUT реализует алгоритм “первым пришел – первым обслужен”. В утилите SQL*Plus имеется средство, называемое SERVEROUTPUT (серверный вывод), команда SQL*Plus, называемая SET SERVEROUTPUT ON, неявно вызывает процедуру DBMS_OUTPUT.ENABLE, которая устанавливает внутренний буфер серверного вывода. Если нужно, можно указать размер буфера с помощью команды:

SET SERVEROUTPUT ON SIZE размер_буфера

где размер_буфера – первоначальный размер буфера (аргумент процедуры DBMS_OUTPUT.ENABLE, вызываемой по умолчанию). Процедура DBMS_OUTPUT.GET_LINES вызывается после окончания блока PL/SQL. Это означает, что результаты будут выводится на экран после завершения блока, а не вовремя его выполнения.

 

 

Рисунок 3. Использование SERVEROUTPUT и PUT_LINE

 

Обзор динамического SQL

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

Выполнять SQL – конструкции можно двумя способами:

- с помощью модуля DBMS_SQL

- посредством внутреннего динамического SQL (для ORACLE 8i).

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

Модуль DBMS_SQL

Алгоритм выполнения операторов с помощью DBMS_SQL следующий:

1. Преобразование SQL – оператора в строку символов,

2. Грамматический разбор строки символов с помощью DBMS_SQL.PARSE,

3. Привязка всех входных переменных с помощью DBMS_SQL.BIND_VARIABLE,

4. Если выполняемый оператор это оператор DML (update, delete, insert) – выполнение его с помощью DBMS_SQL.EXECUTE с последующим считыванием выходных переменных привязки с помощью DBMS_SQL.VARIABLE_VALUE (если нужно),

5. Если оператор является оператором извлечения (select) – описание выходных переменных с помощью DBMS_SQL.DEFINE_COLUMN,

6. Выполнения запроса на выборку с помощью DBMS_SQL.EXECUTE и выборка результатов при помощи DBMS_SQL.FETCH_ROWS и DBMS_SQL.COLUMN_VALUE.

 

Обработка операторов DML посредством DBMS_SQL

Для обработки операторов update, delete, insert средствами модуля DBMS_SQL необходимо последовательно выполнить следующие действия:

 

1. Открыть курсор

Осуществляется посредством вызова процедуры OPEN_CURSOR, описание которой в модуле выглядит следующим образом:

 

OPEN_CURSOR return integer

 

Параметры в данной процедуре отсутствуют.

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

 

2. Выполнить грамматический разбор оператора

При выполнении грамматического разбора оператор направляется на сервер БД. Сервер проверяет его синтаксис и семантику и возвращает ошибку (устанавливая исключительную ситуацию), если нарушены требования грамматики. Кроме того во время разбора определяется план выполнения оператора. Осуществляется грамматический разбор посредством вызова процедуры DBMS_SQL.PARSE, описание которой в модуле имеет следующий вид:

 

procedure PARSE (c in integer,

statement in varchar2,

language_flag in integer).

 

Здесь с – идентификационный номер курсора, предварительно должен быть открыт посредством OPEN_CURSOR,

statement – оператор, грамматический разбор которого выполняется,

language flag – указывает как трактовать оператор, значение NATIVE – режим установленный для той базы данных, с которой выполнено соединение.

 

3. Привязка входных переменных

При выполнении этой операции, заполнители указанные в нем связываются с фактическими переменными. Имена заполнители обычно предваряют символом двоеточия. Процедура BIND_VARIABLE выполняет привязку и объявление имен заполнителей. Размер и тип данных фактических переменных также устанавливается BIND_VARIABLE посредством набора переопределенных вызовов:

 

procedure BIND_VARIABLE (c in integer,

name in varchar2,

value in number),

procedure BIND_VARIABLE (c in integer,

name in varchar2,

value in varchar2),

procedure BIND_VARIABLE (c in integer,

name in varchar2,

value in varchar2,

out_value_size in integer).

 

Здесь параметр name – это имя заполнителя, с которым будет связана переменная, value – реальные данные, которые будут привязываться, тип и размер этой переменной также считываются. При необходимости данные, содержащиеся в этой переменной будут преобразованы. Параметр out_value_size – параметр, задаваемый при привязке переменных varchar2 и char , если указан, то это максимальный ожидаемый размер значения в байтах, если не указан, то используется размер указанный в параметре value.

 

4. Выполнение оператора

Осуществляется посредством функции EXECUTE. Описание её в модуле выглядит следующим образом:

 

function EXECUTE (c in integer) return integer;

 

Здесь с – идентификатор предварительно открытого курсора.

Функция EXECUTE возвращает число отработанных строк (в этом смысле возвращаемое значение аналогично курсорному атрибуту %rowcount). Следует учесть, что возвращаемое значение не определено для операторов выборки, а также и то, что EXECUTE вызывается из выражений программ.

 

 

5. Закрытие курсора

Закрытие курсора осуществляется посредством вызова процедуры CLOSE_CURSOR, описание которой выглядит следующим образом:

 

procedure CLOSE_CURSOR (c in out integer).

 

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

 

Рассмотрим пример:

 

create or replace procedure update_address (p_lname in staff.lname %type,

p_fname in staff.fname %type,

p_newaddress in staff.address %type,

p_rowsupdated out integer) is

v_cursor_id integer;

v_updatestmt varchar2(100);

begin

v_cursor_id: = DBMS_SQL.OPEN_CURSOR;

v_updatestmt: = ‘update staff

set address =: na

where fname=: fname and

lname=: lname’;

DBMS_SQL.PARSE (v_cursor_id, v_updatestmt, DBMS_SQL.NATIVE);

DBMS_SQL.BIND_VARIABLE (v_cursor_id, : na, p_newaddress);

DBMS_SQL.BIND_VARIABLE (v_cursor_id, : fname, p_fname);

DBMS_SQL.BIND_VARIABLE (v_cursor_id, : lname, p_lname);

p_rowsupdated: = DBMS_SQL.EXECUTE (v_cursor_id);

DBMS_SQL.CLOSE_CURSOR(v_cursor_id);

exception

when others then

DBMS_SQL.CLOSE_CURSOR(v_cursor_id);

raise;

end update_address;

 

Обработка запросов на извлечение информации производится путем последовательного выполнения всех ниже перечисленных действий:

 

1. Открытие курсора (OPEN_CURSOR),

2. Выполнение грамматического разбора (PARSE),

3. Выполнение привязки всех входных переменных (BIND_VARIABLE),

4. Описание элементов списка выбора (DEFINE_COLUMN),

5. Исполнения запроса (EXECUTE),

6. Считывания строк (FETCH),

7. Запись результатов в переменные (COLUMN_VALUE),

8. Закрытие курсора (CLOSE_CURSOR).

 

Определение элементов списка выбора

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

 

procedure DEFINE_COLUMN (c in integer,

position in integer,

column in number),

procedure DEFINE_COLUMN (c in integer,

position in integer,

column in varchar2,

column_size in integer)

 

Для переменных varchar2 нужно обязательно указывать параметр column_size, поскольку система поддержки PL/SQL должна знать максимальный размер этих переменных во время выполнения программы, так как в отличие от number , date данные этих типов не имеют фиксированной длины, заранее известной компилятору.

 

Таблица 1 Параметры DEFINE_COLUMN

параметр тип предназначение
с integer идентификатор курсора
position integer позиция пункта списка выбора
column number, varchar2 переменная, определяющая тип и размер выходной переменной. Имя переменной не играет особой роли, однако тип и размер важны. Однако как в DEFINE_COLUMN, так и в COLUMN_VALUE обычно используются одни и те же переменные
column_size integer Максимальный ожидаемый размер данных. Обязателен для тех типов, длина которых не известна заранее системе поддержки PL/SQL

 

 

Считывание строк

Строки набора запроса считываются в буфер посредством вызова функции FETCH_ROWS. Функция описана в модуле следующим образом:

 

function FETCH_ROWS (c in integer)

return integer

 

FETCH_ROWS возвращает число считываемых строк. FETCH_ROWS и COLUMN_VALUE вызывают в цикле несколько раз до тех пор, пока FETCH_ROWS не возвратит нуль.

 

Запись результатов в переменные PL/SQL

Процедуру COLUMN_VALUE следует вызывать после успешного выполнения FETCH_ROWS. Если в выборке не были возвращены строки, (что указывается возвратом 0) COLUMN_VALUE устанавливает для выходной переменной null – значение. Ниже приведено описание процедуры в модуле DBMS_SQL:

 

procedure COLUMN_VALUE (c in integer,

position in integer,

value out number),

procedure COLUMN_VALUE (c in integer,

position in integer,

value out number,

column_error out number,

actual_length out number),

procedure COLUMN_VALUE (c in integer,

position in integer,

value out varchar2),

procedure COLUMN_VALUE (c in integer,

position in integer,

value out varchar2,

column_error out number,

actual_length out number).

 

Таблица 2 Параметры процедуры COLUMN_VALUE

параметр тип предназначение
с integer идентификатор курсора
position integer относительная позиция в списке выбора, как и в DEFINE_COLUMN, позиция первого элемента списка =1
value number, varchar2 выходная переменная, если тип этого параметра отличается от типа, указанного в DEFINE_COLUMN то возникает ошибка, что соответствует исключительной ситуации DBMS_SQL.INCONSISTENT_TYPES
column_error number код ошибки столбца, выдается в виде отрицательного числа. Ошибка будет устанавливать исключительную ситуацию, а column_error позволяет определить какой из столбцов стал причиной конкретной ошибки. Если столбец был успешно прочитан, то column_error=0
actual_length number Если указан, то в данной переменной будет находится исходный размер столбца (размер столбца перед его считыванием). Это удобно в случае, когда размер переменной недостаточен и значение усекается (это также приводит к ошибке)

 

В нижеследующем примере создается процедура, определяющая имена и фамилии сотрудников по заданной для данной процедуры должности сотрудника:

create or replace procedure DynamicQuery (p_position in staff.position %type) is

v_cursor_id integer;

v_select_stmt varchar2(500);

v_first_name staff.fname %type;

v_last_name staff.lname %type;

v_dummy integer;

begin

v_cursor_id: = DBMS_SQL.OPEN_CURSOR;

v_select_stmt: = ‘select lname, fname

from staff

where position =: pos

order by lname’;

DBMS_SQL.PARSE (v_cursor_id, v_select_stmt, DBMS_SQL.NATIVE);

DBMS_SQL.BIND_VARIABLE (v_cursor_id, ‘: pos’, p_position);

DBMS_SQL.DEFINE_COLUMN (v_cursor_id, 1, v_last_name, 25);

DBMS_SQL.DEFINE_COLUMN (v_cursor_id, 2, v_first_name, 25);

v_dummy: = DBMS_SQL.EXECUTE (v_cursor_id);

loop

if DBMS_SQL.FETCH_ROWS (v_cursor_id)=0 then

exit;

end if;

DBMS_SQL.COLUMN_VALUE (v_cursor_id, 1, v_last_name);

DBMS_SQL.COLUMN_VALUE (v_cursor_id, 2, v_first_name);

insert into temp_table (name_col)

values (v_last_name || ’ ’ || v_first_name);

end loop;

DBMS_SQL.CLOSE_CURSOR (v_cursor_id);

commit;

exception

when others then

--Закроем курсор, а затем повторно установим ошибку

DBMS_SQL.CLOSE_CURSOR (v_cursor_id);

raise;

end DynamicQuery;

 

· Варианты заданий

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

 

2. Создать функцию, подсчитывающую среднюю зарплату сотрудников в зависимости от места работы, информацию вынести во временную таблицу, возвращать среднее количество сотрудников на отделение. Функцию создавать средствами модуля DBMS_SQL.

 

3. Создать динамическую процедуру, осуществляющую поиск сотрудника по заданному шаблону и выводящую во временную таблицу всю не null информацию о нем, в выходном параметре процедуры передавать значение “неопределено”в случае если поиск не дал результатов.

 

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

 

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

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

 

7. Создать динамическую процедуру, осуществляющую добавление информации о новых объектах с автоматическим закреплением данного объекта за сотрудниками, у которых меньше объектов, чем в среднем по отделению, если таковых несколько объект закрепить за первым в упорядоченном по алфавиту списке сотрудником.

 

8. Создать динамическую функцию, осуществляющую добавление информации о новых объектах с закреплением их за определенным сотрудником, имя и фамилия которого указываются во входных аргументах функции. Если у данного сотрудника количество закрепленных за ним объектов и так превышает среднее количество на человека по отделению, то отменить ввод. Возвращать TRUE или FALSE в зависимости от того успешно или нет было выполнено добавление.

 

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

 

10. Создать динамическую функцию, запрещающую принимать на работу сотрудников старше 35 лет. Функция должна отклонять попытки выполнения добавлений информации о сотруднике, в случае не соблюдения выше приведенного условия.

 

 

· Контрольные вопросы

1. Поясните принципы серверного вывода в ORACLE 8i ?

2. В чем преимущества процедур с динамическим SQL?

3. Расскажите о порядке выполнения DML – операторов средствами модуля DBMS_SQL.

4. Какие особенности в обработке динамических запросов на извлечение информации?

 

 


Поделиться:



Популярное:

  1. B2 (базовый уровень, время – 4 мин)
  2. I WORK UNDER MANY DIFFICULTIES (я работаю в трудных условиях: «под многими сложностями»)
  3. I ЭТАП: ОБСЛЕДОВАНИЯ (СБОР ДАННЫХ)
  4. III. Вид работы: «Использование информационной базы данных»
  5. IV. Анализ и обработка данных.
  6. А. В. Петровский разработал следующую схему развития групп. Он утверждает, что существует пять уровней развития групп: диффузная группа, ассоциация, кооперация, корпорация и коллектив.
  7. Авторское право - правовое положение авторов и созданных их творческим трудом произведений литературы, науки и искусства.
  8. Адресная, данных, управления
  9. Анализ и интерпретация данных экспериментально-психологического исследования
  10. Анализ исходных данных и разработка математической модели
  11. Анализ экспериментальных данных
  12. Анализируя опыт мирового развития, можно выделить пять наиболее типичных моделей капиталистической экономики, базирующейся на многообразии форм собственности.


Последнее изменение этой страницы: 2016-07-13; Просмотров: 1380; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.159 с.)
Главная | Случайная страница | Обратная связь