Шаг 90 - PL/SQL - Процедуры и их параметры II

Идем дальше по пути познания процедур. Итак, мы с вами рассмотрели тип передаваемых параметров - IN и OUT. Существует еще один тип параметров процедур, а именно как вы уже, наверное, догадываетесь это тип IN OUT - то есть при объявлении это выглядит примерно вот так:

CREATE OR REPLACE PROCEDURE MYPROC(MYPARAM IN OUT NUMBER .......

Вот с этим параметром давайте разберемся подробнее. Давайте сформулируем правила, для такого тип параметров.

IN OUT - этот вид представляет собой комбинацию видов IN и OUT. Значение фактического параметра передается в процедуру при ее вызове. Внутри процедуры формальный параметр может быть считан и в него может быть записано значение. При завершении процедуры и возврате управления в вызывающую среду, содержимое формального параметра присваивается фактическому параметру.

Теперь давайте создадим следующую процедуру примерно вот такого вида:

CREATE OR REPLACE PROCEDURE TESTINOUT(NUM IN OUT NUMBER, DT OUT VARCHAR2)
IS

BEGIN

	SELECT COMPANY INTO DT FROM customers
	WHERE customers.CUST_NUM = NUM;

	SELECT CUST_REP INTO NUM FROM customers
	WHERE customers.CUST_NUM = NUM;

END TESTINOUT;
/

Не торопитесь ее компилировать, давайте порасcуждаем. Итак, теперь NUM параметр IN OUT - как видно второй SELECT принимает его как параметр и возвращает через него значение. То есть принимает условие и вернет результат. Удобно, не так ли? Компилируем:

SQL> CREATE OR REPLACE PROCEDURE TESTINOUT(NUM IN OUT NUMBER, DT OUT VARCHAR2)
  2  IS
  3  
  4  BEGIN
  5  
  6   SELECT COMPANY INTO DT FROM customers
  7   WHERE customers.CUST_NUM = NUM;
  8  
  9   SELECT CUST_REP INTO NUM FROM customers
 10   WHERE customers.CUST_NUM = NUM;
 11  
 12  END TESTINOUT;
 13  /

Процедура создана.

Вот теперь если сделать вот такой вызов:

SET SERVEROUTPUT ON
 
DECLARE 

FRDT VARCHAR2(100);
FRNM NUMBER := 2103;

BEGIN

	TESTINOUT(FRNM, FRDT);
	
	DBMS_OUTPUT.enable;
    DBMS_OUTPUT.put_line('CUSTOMER '||FRDT||' CUST_REP '||TO_CHAR(FRNM));

END;
/

Получаем:

SQL> SET SERVEROUTPUT ON
SQL> 
SQL> DECLARE 
  2  
  3  FRDT VARCHAR2(100);
  4  FRNM NUMBER := 2103;
  5  
  6  BEGIN
  7  
  8   TESTINOUT(FRNM, FRDT);
  9   
 10   DBMS_OUTPUT.enable;
 11      DBMS_OUTPUT.put_line('CUSTOMER '||FRDT||' CUST_REP '||TO_CHAR(FRNM));
 12  
 13  END;
 14  /
CUSTOMER Крупное предприятие CUST_REP 105

Процедура PL/SQL успешно завершена.

Не трудно заметить, что первое значение фактического параметра FRNM равно 2103, а вот вернул он значение 105 - т.е. один параметр выполнил двойную работу. Вполне не плохо. К слову, если вы попытаетесь сделать что-то вроде:

SET SERVEROUTPUT ON
 
DECLARE 

FRDT VARCHAR2(100);

BEGIN

	TESTINOUT(2103, FRDT);
	
END;
/

То получите в ответ следующее:

DECLARE

FRDT VARCHAR2(100);

BEGIN

	TESTINOUT(2103, FRDT);

END;

ORA-06550: Строка 7, столбец 12:
PLS-00363: выражение '2103' не м.б. использовано как адресат назначения
ORA-06550: Строка 7, столбец 2:
PL/SQL: Statement ignored

SQL>

В литерале 2103 нельзя сохранить возвращаемый результат, так как литерал не хранится в памяти после использования. Ну, что я думаю и так очевидно. Надеюсь, с данным типом параметра теперь вам все стало ясно! :)

Давайте теперь остановимся на понятии тела (body) процедуры. Тело процедуры содержит собственно исполняемый код и располагается между ключевыми словами BEGIN и EXCEPTION. Далее идет блок EXCEPTION и END, в котором располагается собственно обработчик исключительной ситуации. Раздел объявлений располагается между операторами CREATE и IS или AS (вот и снова язык Ada!) - а выглядит это все примерно вот так:

CREATE OR REPLACE PROCEDURE [имя процедуры] IS or AS

	зона объявления переменных.

BEGIN

	выполняемый раздел

EXCEPTION

	раздел исключительных ситуаций

END [имя процедуры]

Такой скелет имеет процедура и все что к ней прилагается. Запомните это получше! :)


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Летучий Сергей - 05.02.2004