CREATE OR REPLACE PROCEDURE PTEST(I_PAR IN OUT NUMBER, II_PAR IN OUT VARCHAR2)

IS

BEGIN

I_PAR := 15.6;

II_PAR := 'POIUYTREWQLKJHGFDSA';

END PTEST;

/

Компилируем:

SQL> CREATE OR REPLACE PROCEDURE PTEST(I_PAR IN OUT NUMBER, II_PAR IN OUT VARCHAR2)

2 IS

3

4 BEGIN

5

6 I_PAR := 15.6;

7 II_PAR := 'POIUYTREWQLKJHGFDSA';

8

9 END PTEST;

10 /

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

Вот теперь I_PAR и II_PAR получили неявное ограничение посредством объявлений:

I_PAR := 15.6;

II_PAR := 'POIUYTREWQLKJHGFDSA';

т. е. получилось, что то вроде:

CREATE OR REPLACE PROCEDURE PTEST(I_PAR IN OUT NUMBER(3.4), II_PAR IN OUT VARCHAR2(19))

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

DECLARE

V_STR VARCHAR2(10);

V_NUM NUMBER(3,4);

BEGIN

PTEST(V_NUM, V_STR);

END;

/

Получаем, что-то довольно странное:

SQL> DECLARE

2

3 V_STR VARCHAR2(10);

4 V_NUM NUMBER(3,4);

5

6 BEGIN

7

8 PTEST(V_NUM, V_STR);

9

10 END;

11 /

DECLARE

*

ошибка в строке 1:

ORA-06502: PL/SQL: : буфер символьных строк слишком маленький ошибка числа или значения

ORA-06512: на "MILLER. PTEST", line 7

ORA-06512: на line 8

SQL>

Не сразу ясно, что происходит, так? А все очень просто, V_STR VARCHAR2(10) переопределила ограничение переменной II_PAR при ее явном вызове и запись строки длинной 19 символов в переменную всего в 10 символов привело к ошибке! Очень важно это понимать, иначе в дальнейшем вы запутаетесь совсем! Здесь ошибку вызвала сама вызывающая программа, а не код процедуры, как может показаться! Так вот во избежание ошибок, подобных ORA-06502 при создании процедур документируйте все ограничения налагаемые на фактические параметры - вносите в хранимые процедуры комментарии, а так же кроме описания каждого параметра записывайте функции выполняемые самой процедурой! Вот тогда я думаю, у вас все получится!

НЕ нашли? Не то? Что вы ищете?

Так же единственным способом наложения ограничения на формальный параметр функции является использование оператора %TYPE. Мы с вами о нем говорили. В свете этого можно переписать нашу функцию пример - скажем, вот так:

CREATE OR REPLACE PROCEDURE PTEST(

I_PAR IN OUT CUSTOMERS. CUST_NUM%TYPE,

II_PAR IN OUT PANY%TYPE)

IS

BEGIN

I_PAR := 15.6;

II_PAR := 'POIUYTREWQLKJHGFDSA';

END PTEST;

/

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

SQL> CREATE OR REPLACE PROCEDURE PTEST(

2 I_PAR IN OUT CUSTOMERS. CUST_NUM%TYPE,

3 II_PAR IN OUT PANY%TYPE)

4 IS

5

6 BEGIN

7

8 I_PAR := 15.6;

9 II_PAR := 'POIUYTREWQLKJHGFDSA';

10

11 END PTEST;

12 /

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

Ошибок нет! Значит, все прошло успешно! Как работать с параметрами это дело вкуса, а на него, как говорится, товарищей совсем не бывает! Вот пока можете все это переварить, а я пойду попью чаю! :)

Шаг 92 - PL/SQL - Процедуры и параметры еще немного

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

CREATE OR REPLACE PROCEDURE TEST_POZ(

PR_A IN NUMBER,

PR_B IN NUMBER,

PR_C IN VARCHAR2,

PR_D IN VARCHAR2

)

IS

BEGIN

NULL;

END TEST_POZ;

/

Ничего особенного она проделывать не будет, но зато с явным энтузиазмом будет принимать аж четыре параметра! Компилируем:

SQL> CREATE OR REPLACE PROCEDURE TEST_POZ(

2 PR_A IN NUMBER,

3 PR_B IN NUMBER,

4 PR_C IN VARCHAR2,

5 PR_D IN VARCHAR2

6 )

7 IS

8

9 BEGIN

10

11 NULL;

12

13 END TEST_POZ;

14 /

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

Все прошло успешно, вот и славно! А вот теперь запишем такой анонимный блок:

SET SERVEROUTPUT ON

DECLARE

PR_1 NUMBER;

PR_2 NUMBER;

PR_3 VARCHAR2(100);

PR_4 VARCHAR2(100);

BEGIN

TEST_POZ(PR_1, PR_2, PR_3, PR_4);

END;

/

Запускаем и получаем:

SQL> SET SERVEROUTPUT ON

SQL>

SQL> DECLARE

2

3 PR_1 NUMBER;

4 PR_2 NUMBER;

5 PR_3 VARCHAR2(100);

6 PR_4 VARCHAR2(100);

7

8 BEGIN

9

10 TEST_POZ(PR_1, PR_2, PR_3, PR_4);

11

12 END;

13 /

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

Смотрите, мы объявили четыре параметра и передали их нашей функции, в данном конкретном случае мы применили так называемое - "позиционное представление" (positional notation)! Такой тип передачи параметров применяется во всех языках программирования, например в таком как C и C++! Я сразу рекомендую вам пользоваться именно таким способом передачи! Хотя это еще далеко не все!

Запишем следующий анонимный блок:

SET SERVEROUTPUT ON

DECLARE

PR_1 NUMBER;

PR_2 NUMBER;

PR_3 VARCHAR2(100);

PR_4 VARCHAR2(100);

BEGIN

TEST_POZ(PR_A => PR_1, PR_B => PR_2, PR_C => PR_3, PR_D => PR_4);

END;

/

Получаем:

SQL> SET SERVEROUTPUT ON

SQL>

SQL> DECLARE

2

3 PR_1 NUMBER;

4 PR_2 NUMBER;

5 PR_3 VARCHAR2(100);

6 PR_4 VARCHAR2(100);

7

8 BEGIN

9

10 TEST_POZ(PR_A => PR_1, PR_B => PR_2, PR_C => PR_3, PR_D => PR_4);

11

12 END;

13 /

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

В данном случае я использовал - "именное представление" (named notation), которое PL/SQL унаследовал от языка Ada. В данном случае указываются как формальные, так и фактические параметры. Идем далее. Запишем следующий анонимный блок:

SET SERVEROUTPUT ON

DECLARE

PR_1 NUMBER;

PR_2 NUMBER;

PR_3 VARCHAR2(100);

PR_4 VARCHAR2(100);

BEGIN

TEST_POZ(PR_B => PR_2, PR_C => PR_3, PR_D => PR_4, PR_A => PR_1);

END;

/

Получаем:

SQL> SET SERVEROUTPUT ON

SQL>

SQL> DECLARE

2

3 PR_1 NUMBER;

4 PR_2 NUMBER;

5 PR_3 VARCHAR2(100);

6 PR_4 VARCHAR2(100);

7

8 BEGIN

9

10 TEST_POZ(PR_B => PR_2, PR_C => PR_3, PR_D => PR_4, PR_A => PR_1);

11

12 END;

13 /

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

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

SET SERVEROUTPUT ON

DECLARE

PR_1 NUMBER;

PR_2 NUMBER;

PR_3 VARCHAR2(100);

PR_4 VARCHAR2(100);

BEGIN

TEST_POZ(PR_1, PR_2, PR_C => PR_3, PR_D => PR_4);

END;

/

SQL> SET SERVEROUTPUT ON

SQL>

SQL> DECLARE

2

3 PR_1 NUMBER;

4 PR_2 NUMBER;

5 PR_3 VARCHAR2(100);

6 PR_4 VARCHAR2(100);

7

8 BEGIN

9

10 TEST_POZ(PR_1, PR_2, PR_C => PR_3, PR_D => PR_4);

11

12 END;

13 /

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

Здесь хорошо видно, что позиционное и именное представление можно комбинировать, и использовать совместно. Хотя я думаю, что так легче запутать код, чтобы потом никто нифига не понял! :) Хотя это все оставляется на усмотрение программиста и стиль написания кода! Так же смею заметить, что - чем больше параметров в процедуре, тем сложнее ее вызывать и тем труднее убеждаться в наличии всех требуемых параметров. Если необходимо передать в процедуру или получить из нее достаточно большое число параметров, то рекомендуется определить тип записи, полями которой будут эти параметры. Затем можно использовать единственный параметр имеющий тип записи. В PL/SQL - так же не установлено явное ограничение на количество передаваемых в процедуру параметров.

Значение параметров по умолчанию...

Дело в том, что как и все переменные формальные параметры процедуры могут иметь значения по умолчанию. В таком случае значение параметру, имеющему такое определение можно не передавать. Если же фактический параметр все-таки передан, то принимается именно его значение. Итак, значение по умолчанию указывается вот так:

------------ имя_парметра [вид] {:= | DEFAULT} исходное_значение ------------

Давайте перепишем нашу первую процедуру с параметрами по умолчанию:

CREATE OR REPLACE PROCEDURE TEST_POZ(

PR_A IN NUMBER,

PR_B IN NUMBER,

PR_C IN VARCHAR2 := 'HELLO',

PR_D IN VARCHAR2 DEFAULT 'WORLD!!!')

IS

BEGIN

NULL;

END TEST_POZ;

/

Получаем:

SQL> CREATE OR REPLACE PROCEDURE TEST_POZ(

2 PR_A IN NUMBER,

3 PR_B IN NUMBER,

4 PR_C IN VARCHAR2 := 'HELLO',

5 PR_D IN VARCHAR2 DEFAULT 'WORLD!!!')

6 IS

7

8 BEGIN

9

10 NULL;

11

12 END TEST_POZ;

13 /

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

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

Шаг 93 - PL/SQL - Функции

Вот теперь, наконец, давайте рассмотрим такое понятие как функции PL/SQL. Раньше в шагах мы с вами рассмотрели так называемые встроенные функции PL/SQL. А сейчас мы попробуем сами научится писать то, что называется функциями. По своей сути функция это то же, что и процедура, она может принимать параметры по всем тем же правилам, что и процедуры, и кроме всего она может возвращать значения! Но не применением OUT типа передаваемого параметра, а сама по себе. То есть функция, принимает параметры и возвращает одно(!), значение! В принципе в функции можно применять параметры с типом OUT - но это очень плохая идея! Такой метод я использовать не рекомендую! Определение функции таково:

-------------- CREATE [OR REPLACE] FUNCTION - имя_функции ------------------------------------ (аргумент [IN] [OUT] [IN OUT] тип, ..... ) AS [IS] ---------------------------- тело процедуры ---------------------------------------------------------------- RETURN (возвращаемое_значение) ----------------------------------

Кое-что вам уже знакомо, за исключением того, что присутствует оператор RETURN. Посредством этого оператора функция возвращает значение. Функция, как правило, вызывается внутри какого-либо определения, т. к. вызывать функцию как оператор нет смысла. Но как вы дальше убедитесь, с помощью функция можно делать очень полезные вещи. Итак, давайте напишем функцию преобразования BOOLEAN типа в тип VARCHAR2 - это самая простая задачка во всех учебниках. Итак:

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8