Oracle вызов процедуры с параметром out
Идем дальше по пути познания процедур. Итак, мы с вами рассмотрели тип передаваемых параметров - IN и OUT. Существует еще один тип параметров процедур, а именно как вы уже, наверное, догадываетесь это тип IN OUT - то есть при объявлении это выглядит примерно вот так:
Вот с этим параметром давайте разберемся подробнее. Давайте сформулируем правила, для такого тип параметров.
IN OUT - этот вид представляет собой комбинацию видов IN и OUT. Значение фактического параметра передается в процедуру при ее вызове. Внутри процедуры формальный параметр может быть считан и в него может быть записано значение. При завершении процедуры и возврате управления в вызывающую среду, содержимое формального параметра присваивается фактическому параметру.
Теперь давайте создадим следующую процедуру примерно вот такого вида:
Не торопитесь ее компилировать, давайте порасcуждаем. Итак, теперь NUM параметр IN OUT - как видно второй SELECT принимает его как параметр и возвращает через него значение. То есть принимает условие и вернет результат. Удобно, не так ли? Компилируем:
Вот теперь если сделать вот такой вызов:
Не трудно заметить, что первое значение фактического параметра FRNM равно 2103, а вот вернул он значение 105 - т.е. один параметр выполнил двойную работу. Вполне не плохо. К слову, если вы попытаетесь сделать что-то вроде:
То получите в ответ следующее:
В литерале 2103 нельзя сохранить возвращаемый результат, так как литерал не хранится в памяти после использования. Ну, что я думаю и так очевидно. Надеюсь, с данным типом параметра теперь вам все стало ясно! :)
Давайте теперь остановимся на понятии тела (body) процедуры. Тело процедуры содержит собственно исполняемый код и располагается между ключевыми словами BEGIN и EXCEPTION. Далее идет блок EXCEPTION и END, в котором располагается собственно обработчик исключительной ситуации. Раздел объявлений располагается между операторами CREATE и IS или AS (вот и снова язык Ada!) - а выглядит это все примерно вот так:
Такой скелет имеет процедура и все что к ней прилагается. Запомните это получше! :)
Процедура представляет собой модуль, выполняющий одно или несколько действий. Поскольку вызов процедуры в PL/SQL является отдельным исполняемым оператором, блок кода PL/SQL может состоять только из вызова процедуры. Процедуры относятся к числу ключевых компонентов модульного кода, обеспечивающих оптимизацию и повторное использование программной логики.
Общий формат процедуры PL/SQL выглядит так:
Основные элементы этой структуры:
- схема — имя схемы, которой будет принадлежать процедура (необязательный аргумент). По умолчанию применяется имя схемы текущего пользователя. Если значение схемы отлично от имени схемы текущего пользователя, то этот пользователь должен обладать привилегиями для создания процедуры в другой схеме.
- имя — имя процедуры.
- параметр — необязательный список параметров, которые применяются для передачи данных в процедуру и возврата информации из процедуры в вызывающую программу.
- AUTHID — определяет, с какими разрешениями будет вызываться процедура: создателя (владельца) или текущего пользователя. В первом случае процедура выполняется с правами создателя, во втором — с правами вызывающего.
- объявления — объявления локальных идентификаторов этой процедуры. Если объявления отсутствуют, между ключевыми словами IS и BEGIN не будет никаких выражений.
- ACCESSIBLE BY (Oracle Database 12c) — ограничивает доступ к процедуре программными модулями, перечисленными в круглых скобках.
- исполняемые команды — команды, выполняемые процедурой при вызове. Между ключевыми словами BEGIN и END или EXCEPTION должна находиться по крайней мере одна исполняемая команда.
- обработчики исключений — необязательные обработчики исключений для процедуры. Если процедура не обрабатывает никаких исключений, слово EXCEPTION можно опустить и завершить исполняемый раздел ключевым словом END .
На рис. 1 показан код процедуры apply_discount , который содержит все четыре раздела, характерных для именованных блоков PL/SQL.
Рис. 1. Код процедуры
Дублирование формальных параметров
При выполнении динамической команды SQL связь между формальными и фактическими параметрами устанавливается в соответствии с их позициями. Однако интерпретация одноименных параметров зависит от того, какой код используется — SQL или PL/SQL .
- При выполнении динамической команды SQL (DML - или DDL-строки, не оканчивающейся точкой с запятой) параметр подстановки нужно задать для каждого формального параметра, даже если их имена повторяются.
- При выполнении динамического блока PL/SQL (строки, оканчивающейся точкой с запятой) нужно указать параметр подстановки для каждого уникального формального параметра.
Далее приведен пример динамической команды SQL с повторяющимися формальными параметрами. Особое внимание обратите на повторяющийся параметр подстановки val_in в секции USING :
А вот динамический блок PL/SQL с повторяющимися формальными параметрами — для него в секции USING параметр val_in задан только один раз:
Формальные и фактические параметры
Очень важно понимать различия между формальными и фактическими параметрами. Формальные параметры представляют собой имена, объявленные в списке параметров заголовка модуля, тогда как фактические параметры — это значения и выражения, которые помещаются в список параметров при вызове модуля.
Различия между формальными и фактическими параметрами нам также поможет понять функция total_sales . Ее заголовок выглядит так:
Формальные параметры total_sales :
company_id_in — первичный ключ (идентификатор компании).
status_in — статус заказов, включаемых в вычисление.
Эти формальные параметры не существуют за пределами модуля. Их можно рассматривать как своего рода «заместителей» реальных значений, передаваемых модулю при его использовании в программе (то есть фактических параметров).
При вызове total_sales необходимо предоставить два аргумента, которыми могут быть переменные, константы или литералы (для параметров в режимах OUT и IN OUT это должны быть переменные). В следующем примере переменная company_id содержит первичный ключ, указывающий на запись компании. В первых трех вызовах total_sales функции передаются жестко запрограммированные значения статуса заказов, а в последнем вызове статус не указан; в этом случае функция присваивает параметру status_in значение по умолчанию, указанное в заголовке:
При вызове total_sales вычисляются значения всех фактических параметров. Результаты вычислений присваиваются соответствующим формальным параметрам внутри функции (обратите внимание: это относится только к параметрам IN и IN OUT; параметры режима OUT не копируются).
Формальные параметры и соответствующие им фактические параметры (указанные при вызове) должны относиться к одинаковым или совместимым типам данных. Во
многих ситуациях PL/SQL выполняет преобразования данных автоматически, однако лучше по возможности обходиться без неявных преобразований. Используйте такие функции, как TO_CHAR и TO_DATE , чтобы точно знать, какие данные получает модуль.
Вызов процедуры
Процедура вызывается как исполняемая команда PL/SQL. Другими словами, ее вызов должен заканчиваться точкой с запятой (;) и может предшествовать другим командам SQL либо PL/SQL (если таковые имеются) в исполняемом разделе блока PL/SQL или следовать за ними:
Если процедура не имеет параметров, она может вызываться с пустыми круглыми скобками или без них:
Режимы передачи параметров в SQL
При передаче значений параметров команды SQL можно использовать один из трех режимов: IN ( только чтение, действует по умолчанию), OUT (только запись) или IN OUT (чтение и запись). При выполнении динамического запроса все параметры команды SQL , за исключением параметра в секции RETURNING , должны передаваться в режиме IN :
Параметры подстановки команды SQL , передаваемые в режимах OUT и IN OUT , используются прежде всего при выполнении динамического PL/SQL . В этом случае режимы передачи параметров соответствуют аналогичным режимам обыкновенных программ PL/SQL , а также использованию переменных в динамических блоках PL/SQL . Несколько общих рекомендаций, касающихся использования секции USING при выполнении динамического PL/SQL :
- В качестве параметра подстановки, передаваемого в режиме IN , может быть задан любой элемент соответствующего типа: литеральное значение, именованная константа, переменная или сложное выражение. Такой элемент сначала вычисляется, а затем передается в динамический блок PL/SQL .
- Для значения параметра динамической команды в режиме OUT или IN OUT следует объявить переменную.
- Значения можно подставлять только вместо тех параметров динамического блока PL/SQL , тип которых поддерживается SQL . Например, если параметр процедуры имеет тип BOOLEAN, его значение нельзя задать или считать с помощью секции USING .
Это ограничение частично снято в версии 12.1 и выше. Теперь разрешается подстановка многих типов PL/SQL , включая типы записей и коллекций, но подстановка BOOLEAN по-прежнему запрещена.
Давайте рассмотрим механизм передачи параметров на примерах. Вот заголовок процедуры с параметрами IN, OUT и IN OUT :
Пример блока с динамическим вызовом этой процедуры:
Поскольку процедура имеет четыре параметра, в секции USING также должно быть указано четыре элемента. Для первых двух параметров, передаваемых в режиме IN , следует задать литеральные значения или выражения, а следующие два элемента должны быть именами переменных, так как для них заданы режимы OUT и IN OUT .
Но что, если два и более формальных параметра имеют одинаковые имена?
Команда RETURN
Ключевое слово RETURN обычно ассоциируется с функциями, поскольку они должны возвращать значения. Однако PL/SQL позволяет использовать команду RETURN в процедурах. Версия этой команды для процедур не принимает выражений и не может возвращать значения в вызывающий программный модуль — она просто прекращает выполнение процедуры и возвращает управление вызывающему коду.
Использовать эту разновидность RETURN не рекомендуется, поскольку в этом случае в процедуре появляются две и более точки выхода, а это усложняет логику выполнения. Избегайте использования RETURN и GOTO для обхода нормальной управляющей структуры в программных элементах.
Для передачи информации между модулем и вызывающим блоком PL/SQL используются параметры.
Параметры модуля, являющиеся частью его заголовка (или сигнатуры), являются не менее важными компонентами модуля, чем находящиеся в нем исполняемые команды. Заголовок программы иногда называется контрактом между автором и пользователями. Конечно, автор должен позаботиться о том, чтобы модуль выполнял свою задачу. Но ведь модули создаются именно для того, чтобы их можно было вызывать повторно — в идеале более чем из одного модуля. Если список параметров плохо составлен, то другим программистам будет сложно применять такой модуль. В таком случае уже будет неважно, насколько хорошо он написан.
Многие разработчики не уделяют должного внимания наборам параметров своих модулей. Следующие рекомендации помогут вам сделать правильный выбор:
- Количество параметров. Если процедура или функция имеет слишком мало параметров, это снижает ее универсальность; с другой стороны, слишком большое количество параметров усложняет ее повторное использование. Конечно, количество параметров в основном определяется требованиями программы, но существуют разные варианты их определения (например, несколько параметров можно объединить в одну запись).
- Типы параметров. При выборе типа необходимо учитывать, для каких целей будут использоваться параметры: только для чтения, только для записи, для чтения и записи.
- Имена параметров. Параметрам следует присваивать простые имена, отражающие их назначение в модуле.
- Значения по умолчанию. Когда параметру следует задать значение по умолчанию, а когда нужно заставить программиста ввести определенное значение?
PL/SQL предоставляет много средств эффективного планирования. В этом разделе представлены все элементы определения параметров.
Режимы передачи параметров
При определении параметра также указывается допустимый способ его применения. Он задается с помощью одного из трех указанных в таблице режимов.
Режим | Предназначение | Использование параметров |
IN | Только для чтения | Значение параметра может применяться, но не может быть изменено в модуле. Если режим параметра не задан, используется режим IN |
OUT | Только для записи | В модуле можно присвоить значение параметру, но нельзя использовать его. Впрочем, это «официальное» определение — на самом деле Oracle позволяет читать значение параметра OUT в подпрограмме |
IN OUT | Для чтения и записи | В модуле можно использовать и изменять значение параметра |
Режим параметра указывается непосредственно после его имени, но перед типом данных и необязательным значением по умолчанию. В следующем заголовке процедуры задействованы все три режима передачи параметров:
Процедура predict_activity принимает дату последнего действия ( last_date ) и описание этого действия ( task_desc_inout ). Возвращает она два значения: описание действия (возможно, модифицированное) и дату следующего действия (next_date_out). Поскольку параметр task_desk_inout передается в режиме IN OUT , программа может читать и изменять его значение.
Режим IN
Режим IN используется по умолчанию; если режим параметра не задан, параметр автоматически считается определенным в режиме IN. Тем не менее я рекомендую всегда указывать режим параметра, чтобы предполагаемое использование было явно указано в коде.
В заголовке программы параметрам IN могут присваиваться значения по умолчанию (см. раздел «Значения по умолчанию»).
Фактическим значением параметра IN может быть переменная, именованная константа, литерал или сложное выражение. Все следующие вызовы display_title допустимы:
А если вам потребуется передать данные из своей программы? В таком случае используйте параметр OUT или IN OUT — или рассмотрите возможность преобразования процедуры в функцию.
Режим OUT
Как вы, вероятно, уже поняли, параметр OUT по смыслу противоположен параметру IN. Параметры OUT могут использоваться для возвращения значений из программы вызывающему блоку PL/SQL. Параметр OUT сходен с возвращаемым значением функции, но он включается в список параметров, и количество таких параметров не ограничено (строго говоря, PL/SQL разрешает использовать до 64 000 параметров, но на практике это вряд ли можно считать ограничением).
В программе параметр OUT работает как неинициализированная переменная. Собственно, параметр OUT вообще не содержит никакого значения до успешного завершения вызванной программы (если только вы не использовали ключевое слово NOCOPY . Во время выполнения программы все операции присваивания параметру OUT в действительности выполняются с внутренней копией параметра. Когда программа успешно завершается и возвращает управление вызывающему блоку, значение локальной копии перемещается в параметр OUT. После этого значение становится доступным в вызывающем блоке PL/SQL.
У правил, относящихся к параметрам OUT , есть несколько практических следствий:
- Параметрам OUT нельзя задавать значения по умолчанию. Значение параметра OUT может задаваться только в теле модуля.
- Все операции присваивания параметрам OUT отменяются при инициировании исключения в программе. Так как значение параметра OUT присваивается только в случае успешного завершения программы, все промежуточные присваивания игнорируются. Если обработчик не перехватит исключение и не присвоит значение параметру OUT, параметр останется неизменным. Переменная сохранит значение, которое она имела до вызова программы.
- Фактический параметр, соответствующий формальному параметру OUT, не может быть константой, литералом или выражением. Иначе говоря, он должен поддерживать присваивание.
Как упоминается выше в таблице, Oracle позволяет прочитать значение параметра OUT в подпрограмме. Это значение изначально всегда равно NULL , но после его присваивания в подпрограмме оно становится «видимым», как показывает следующий сценарий:
Режим IN OUT
В параметре IN OUT можно передавать значения программе и возвращать их на сторону вызова (либо исходное, неизменное значение, либо новое значение, заданное в программе). На параметры IN OUT распространяются два ограничения параметров OUT:
- Параметр IN OUT не может быть константой, литералом или выражением.
- Фактический параметр IN OUT должен быть переменной. Он не может быть константой, литералом или выражением, потому что эти форматы не могут использоваться PL/SQL в качестве приемника для размещения исходящих значений.
Других ограничений для параметров IN OUT нет.
Параметры IN OUT могут использоваться в обеих сторонах присваивания, потому что они работают как инициализированные переменные. PL/SQL не теряет значение параметра IN OUT в начале выполнения программы. Это значение может использоваться в программе там, где это необходимо.
Процедура combine_and_format_names объединяет имя и фамилию в заданном формате (« LAST, FIRST » или « FIRST LAST »). Процедура получает имя и фамилию, которые преобразуются к верхнему регистру. В ней продемонстрированы все три режима параметров:
Параметры имени и фамилии должны задаваться в режиме IN OUT . Параметр full_name_ out должен быть параметром OUT , потому что процедура возвращает результат объединения имени и фамилии. Наконец, параметр name_format_in, содержащий форматную строку, объявляется в режиме IN, потому что он описывает способ форматирования, но никак не изменяется в процедуре.
Каждый режим параметров имеет свои характеристики и предназначение. Тщательно выбирайте режим, назначаемый вашим параметрам, чтобы они правильно использовались в модулях.
Определяйте формальные параметры в режимах OUT и IN OUT только в процедурах. Функции должны возвращать всю свою информацию исключительно командой RETURN . Выполнение этой рекомендации упростит понимание и использование ваших подпрограмм. Кроме того, функции с параметрами OUT и IN OUT не могут вызываться из команд SQL .
Тело процедуры
В теле процедуры содержится код, необходимый для реализации этой процедуры; тело состоит из объявления, исполняемого раздела и раздела исключений этой процедуры. Все, что следует за ключевым словом IS, образует тело процедуры. Разделы исключений и объявлений не являются обязательными. Если обработчики исключений отсутствуют, опустите ключевое слово EXCEPTION и завершите процедуру командой END .
Заголовок процедуры
Часть определения процедуры, предшествующая ключевому слову IS, называется заголовком процедуры, или сигнатурой. Заголовок предоставляет программисту всю информацию, необходимую для вызова процедуры:
- Имя процедуры.
- Условие AUTHID (если имеется).
- Список параметров (если имеется).
- Список ACCESSIBLE BY (если имеется — новая возможность Oracle Database 12c).
В идеале программист при виде заголовка процедуры должен понять, что делает эта процедура и как она вызывается.
Заголовок процедуры apply_discount из предыдущего раздела выглядит так:
Он состоит из типа модуля, имени и списка из двух параметров.
3 Answers 3
The procedure requires one parameter, so - provide it.
One option, which works everywhere, is to use an anonymous PL/SQL block:
Another one works in SQL*Plus (or any other tool which is capable of simulating it):
when i run Query of greetings procedure, i am getting "Procedure GREETINGS compiled" instead of "PL/SQL procedure successfully completed". Is this ok?
Compiled <> completed. Once you have successfully compiled it, you can run it and - if everything goes OK - it'll be successfully completed. Therefore, yes - the first step is OK.
Regarding the call example, this is explained in EXECUTE recognizes a stored procedure, CALL does not. It's not obvious from the syntax documentation but it does require brackets, so it is (rather unhelpfully) rejecting the whole thing and giving the impression that greetings is the problem, when actually it is not:
while using the mandatory brackets gets you the real issue:
As others have pointed out, you are missing the parameter.
execute is just a handy SQL*Plus shortcut for the PL/SQL block begin xxx; end; which is less fussy about brackets and gives the same error message with or without them.
( variable and print are SQL*Plus commands and may not be supported in other environments.)
Мы рассмотрели несколько примеров использования параметров с NDS . Давайте познакомимся с различными правилами и специальными ситуациями, которые могут вам встретиться при передаче параметров.
SQL -запросу могут передаваться только выражения (литералы, переменные, сложные выражения), заменяющие формальные параметры в строке значениями данных. Не допускается передача имен элементов схемы (таблиц, столбцов и т. д.) или целых фрагментов кода SQL (например, условий WHERE ), которые должны строиться посредством конкатенации.
Допустим, вы хотите создать процедуру для очистки заданного представления или таблицы. Первая версия может выглядеть примерно так:
При упрощении процедуры до следующего вида:
Почему же в NDS (как, впрочем, и в пакете DBMS_SQL ) имеется такое ограничение? При передаче строки команде EXECUTE IMMEDIATE исполняющее ядро должно прежде всего выполнить синтаксический анализ команды, чтобы убедиться в правильности ее определения. PL/SQL может определить, что следующая команда определена правильно, даже не зная значения параметра :xyz:
Но корректность следующий команды PL/SQL проверить не сможет:
По этой причине в данной ситуации необходимо использовать конкатенацию:
Передача значений NULL
При передаче NULL в качестве параметра подстановки — например, как в команде:
Что же делать, если вам потребуется передать в динамический код значение NULL ? Это можно сделать двумя способами.
Во-первых, значение можно скрыть в переменной, для чего проще всего использовать неинициализированную переменную подходящего типа:
Во-вторых, с помощью функции преобразования типа можно явно преобразовать NULL в типизированное значение:
Связывание формальных и фактических параметров в PL/SQL
Каким образом при выполнении программы определяется, какому формальному параметру должен соответствовать фактический параметр? PL/SQL предлагает два метода установления такого соответствия:
- по позиции (неявное связывание);
- по имени (явное связывание с указанием имени формального параметра и обозначения = >).
Позиционное связывание
Во всех приводившихся ранее примерах применялось связывание параметров в соответствии с их позицией. При использовании этого способа PL/SQL принимает во внимание относительные позиции параметров, то есть N-й фактический параметр в вызове программы связывается с N-м формальным параметром в заголовке программы. В следующем примере PL/SQL связывает первый фактический параметр : order. company_id с первым формальным параметром company_id_in , а второй фактический параметр 'N' — со вторым формальным параметром status_in :
Метод позиционного связывания параметров, безусловно, является более наглядным и понятным (рис. 3).
Рис. 3. Позиционное связывание параметров
связывание по имени
Чтобы установить соответствие параметров по имени, следует при вызове подпрограммы явно связать формальный параметр с фактическим. Для этого используется комбинация символов =>:
Поскольку имя формального параметра указано явно, PL/SQL уже не нужно учитывать порядок параметров. Поэтому в данном случае при вызове модуля не обязательно перечислять параметры в порядке их следования в заголовке. Функцию total_sales можно вызывать любым из двух способов:
В одном вызове можно комбинировать оба метода связывания фактических и формальных параметров:
При этом все «позиционные» параметры должны быть перечислены перед «именованными», как в приведенном примере. Позиционному методу необходима начальная точка для отсчета позиций, которой может быть только первый параметр. Если разместить «именованные» параметры перед «позиционными», PL/SQL собьется со счета. Оба вызова total_sales , приведенные ниже, недопустимы. В первой команде «именованные» параметры указываются до «позиционных», а во второй используется позиционная запись, но параметры перечислены в неверном порядке. В этом случае PL/SQL пытается преобразовать 'N' к типу NUMBER (для параметра company_id ):
Преимущества связывания по имени
Возникает резонный вопрос: зачем использовать связывание по имени? У него есть два основных преимущества:
- Повышение информативности. При использовании связывания по имени вызов программы содержит сведения о формальных параметрах, с которыми ассоциируются фактические значения. Если вы не знаете, что делают модули, вызываемые приложением, наличие имен формальных параметров помогает понять назначение конкретного программного вызова. В некоторых средах разработки именно по этой причине связывание по имени считается стандартным. Эта причина особенно актуальна в том случае, когда имена формальных параметров строятся по схеме с присоединением суффикса режима. Только взглянув на вызов процедуры или функции, разработчик сразу видит, в каком направлении передаются те или иные данные.
- Гибкость при описании параметров. Вы имеете возможность размещать параметры в удобном для работы порядке (конечно, это не значит, что при вызове аргументы можно перечислять так, как вам заблагорассудится!) и включать в список только те из них, которые действительно необходимы. В сложных приложениях иногда создаются процедуры с десятками параметров. Но как вы знаете, любой параметр, значение которого определяется по умолчанию, при вызове модуля может быть опущен. Разработчик может передать процедуре только те значения, которые необходимы для решения текущей задачи.
Давайте посмотрим, как реализовать все эти преимущества в программе. Возьмем для примера следующий заголовок:
Анализ списка параметров приводит нас к следующим выводам:
- Минимальное количество аргументов, которые должны передаваться business_as_ usual , равно 3. Чтобы определить его, сложите количество параметров IN, не имеющих значения по умолчанию, с количеством параметров OUT и IN OUT.
- При использовании связывания по позиции программа может вызываться с четырьмя или пятью аргументами, потому что последний параметр объявлен в режиме IN со значением по умолчанию.
- Для хранения значений, возвращаемых параметрами OUT и IN OUT, понадобятся как минимум две переменные.
С таким списком параметров программа может вызываться несколькими способами:
- Связывание только по позиции: задаются все фактические параметры. Обратите внимание, как трудно вспомнить, какой формальный параметр связывается с каждым из этих значений (и каков его смысл):
- Связывание только по позиции: минимальное количество фактических параметров. Понять смысл вызова все еще нелегко:
- Связывание только по имени с сохранением исходного порядка. Обратите внимание: смысл вызова business_as_usual вполне понятен и не требует пояснений:
- Все параметры IN пропускаются, и для них используются значения по умолчанию (другая важная возможность связывания по имени):
- Связывание по имени с изменением порядка следования фактических параметров и передачей неполного списка:
- Объединение связывания по имени и по позиции. Список параметров начинается со связывания по позиции, а после перехода на связывание по имени вернуться к позиционному связыванию уже не удастся:
Как видите, механизм передачи аргументов в PL/SQL весьма гибок. Как правило, связывание по имени способствует написанию кода, который лучше читается и создает меньше проблем с сопровождением. От вас потребуется совсем немного: найти и записать имена параметров.
Квалификатор режима параметра NOCOPY
PL/SQL предоставляет возможность изменить определение параметра при помощи конструкции NOCOPY . NOCOPY требует, чтобы компилятор PL/SQL не создавал копии аргументов OUT и IN — и в большинстве случаев компилятор это требование удовлетворяет. NOCOPY используется прежде всего для повышения эффективности передачи больших конструкций (например, коллекций) в аргументах IN OUT .
Значения по умолчанию
Как было показано в предыдущих примерах, параметрам IN можно задать значения по умолчанию. Если параметр IN имеет значение по умолчанию, включать этот параметр в вызов программы не обязательно. Значение по умолчанию параметра вычисляется и используется программой только в том случае, если параметр не был включен в список при вызове. Конечно, для всех параметров IN OUT фактические параметры должны включаться в список. Значение по умолчанию определяется для параметра так же, как для объявляемой переменной. Предусмотрены два способа задания значений по умолчанию — с ключевым словом DEFAULT и с оператором присваивания ( := ):
Значения по умолчанию позволяют вызывать программы с разным количеством фактических параметров. Программа использует значения по умолчанию для всех незаданных параметров, а для параметров в списке значения по умолчанию заменяются указанными значениями. Несколько примеров разных вариантов использования связывания по позиции:
В первом вызове оба параметра задаются явно. Во втором вызове задается только первый фактический параметр, поэтому born_at_in присваивается текущая дата и время. В третьем вызове параметры вообще не указаны, поэтому круглые скобки отсутствуют (то же относится и к последнему вызову, в который включены пустые круглые скобки). Оба значения по умолчанию используются в теле процедуры.
Чтобы пропустить начальные параметры, имеющие значения по умолчанию, необходимо использовать связывание по имени. Включая имена формальных параметров, можно указать только те параметры, для которых необходимо передать значения:
Error starting at line : 1 in command - CALL GREETINGS Error report - ORA-06576: not a valid function or procedure name 06576. 00000 - "not a valid function or procedure name" *Cause: Could not find a function (if an INTO clause was present) or a procedure (if the statement did not have an INTO clause) to call. *Action: Change the statement to invoke a function or procedure iam getting this error for
Not the source of your issue but a couple of style suggestions. First, if you have a piece of code that does not update data and merely returns a result, that should really be a function not a procedure. If it was a function, you could easily SELECT it rather than needing to build an anonymous block to call it. Second, since cnt is numeric, you really want to declare the parameter to be numeric rather than a varchar2 .
Метка END
Вы можете указать имя процедуры за завершающим ключевым словом END :
Имя служит меткой, явно связывающей конец программы с ее началом. Привыкните к использованию метки END . Она особенно полезна для процедур, занимающих несколько страниц или входящих в серию процедур и функций в теле пакета.
Определение параметров
Формальные параметры определяются в списке параметров программы. Синтаксис определения параметров очень близок к синтаксису объявления переменных в разделе объявлений блока PL/SQL . Впрочем, существуют два важных различия : во-первых, для параметров определяется режим передачи, которого нет у объявлений переменных; во-вторых, объявление параметра должно быть неограниченным.
Ограниченное объявление устанавливает некоторые ограничения для значений, которые могут присваиваться переменной, объявленной с этим типом. Например, следующее объявление переменной company_name ограничивает переменную 60 символами:
При объявлении параметра ограничивающая часть опускается:
Читайте также: