Непоследовательное поведение при выполнении функции из Oracle SQL * Plus? - PullRequest
2 голосов
/ 05 февраля 2012

Я новичок в Oracle и SQL и пытаюсь выполнить простую тестовую функцию из SQL * Plus.Моя функция называется tf (для функции тестирования), и она определяется в файле с именем tf.sql следующим образом:

create or replace
function
tf
(
 arg1 in varchar2
)
return number

as

return_value number;

begin

return_value := 0;
dbms_output.put_line('Argument 1 = ' || arg1);
return return_value;

end;
/

Я могу успешно загрузить эту функцию в Oracle с помощью следующей команды;

SQL> start ./tf.sql

В результате выполнения этой команды SQL * Plus просто сообщает:

Function created.

Когда я затем выполняю следующую команду из командной строки SQL * Plus (после того, как я вызвал setвыход сервера включен);

SQL> exec dbms_output.put_line(SYSTEM.TF('Hello'));

Я получаю следующий вывод:

Argument = Hello
0

PL/SQL procedure successfully completed.

Теперь, если я попытаюсь выполнить свою функцию непосредственно из командной строки SQL * Plus, используя следующую команду;

SQL> exec SYSTEM.TF('Hello');

затем я получаю следующее сообщение об ошибке от SQL * Plus;

BEGIN SYSTEM.TF('Hello'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00221: 'TF' is not a procedure or is undefined
ORA-06550: ;ine 1, column 7
PL/SQL: Statement ignored

Кто-нибудь может пролить свет на это для меня?Я не могу понять, почему моя функция выполняется успешно в первом случае, но не во втором случае.

Если я выполняю следующую команду из командной строки SQL * Plus;

SQL> select * from user_objects where object_name = 'TF';

тогда я получу следующие результаты:

OBJECT_NAME
-----------
TF
SUBOBJECT_NAME
--------------
OBJECT_ID
---------
74475
DATA_OBJECT_ID
--------------
OBJECT_TYPE
-----------
FUNCTION
CREATED
-------
05-FEB-12
LAST_DDL_
---------
05-FEB-12
TIMESTAMP
---------
2012-02-05:02:11:15
STATUS
------
VALID
T
-
N
G
-
N
S
-
N
EDITION_NAME
------------
1

Любая помощь по этому вопросу будет очень ценна.

Заранее спасибо.

Крейг

Ответы [ 2 ]

6 голосов
/ 05 февраля 2012

exec не работает с функциями, потому что не знает, что делать с возвращаемым значением. Это похоже на обычный оператор PL / SQL; если вы вызываете функцию, вы должны присвоить возвращаемое значение чему-либо.

Если вы хотите использовать функцию в SQL * Plus, вы должны использовать вместо нее SQL:

select tf('asdf') from dual;

Кроме того, вы никогда не должны создавать объекты в SYSTEM. Это может вызвать некоторые действительно странные проблемы.

3 голосов
/ 05 февраля 2012

Исходя из ответа @jonearles, который подчеркивает разницу между функцией и процедурой с точки зрения SQL * Plus и комментарием @MS Stp, можно выполнить один из следующих способов:

variable rc number;
exec :rc := tf('Hello');

Argument = Hello

PL/SQL procedure successfully completed.

Дляпосмотрите код возврата, который вы можете затем сделать:

print rc
0

exec - это просто сокращение для анонимного блока PL / SQL, как вы можете видеть из полученного сообщения об ошибке.variable позволяет объявлять переменную связывания на уровне SQL * Plus, а не в блоке.Вы также можете объявить аргумент как переменную связывания и установить его с помощью отдельного вызова exec:

variable rc number;
variable arg varchar2(5);
exec :arg := 'Hello';
exec :rc := tf(:arg);

Я часто использую эту конструкцию для тестирования существующего вызова процедуры, например, что-то скопированное из кода Pro * Cбез необходимости замены переменных в этом вызове на фиксированные значения.Это может упростить повторный вызов с разными аргументами, и вы можете повторно использовать переменные в нескольких вызовах, чтобы позже вы могли передать :rc другой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...