正在从文件执行 PL/SQL 函数
Executing PL/SQL functions from a file
我正在使用 SQL*Plus 并且有一个名为 functions.sql
的文件,其中包含 3 个 PL/SQL 函数:
create or replace function getcustnamebyid (id number) return varchar2(30)
is
...
begin
...
end;
/
create or replace function getspcommbyid (id number) return float
is
...
begin
...
/
create or replace function iscommok (comm float) return boolean
is
...
begin
...
end;
/
我正在尝试在 driver.sql
程序中调用这些函数。我尝试了以下操作,但出现 PL/SQL: ORA-00904: "FUNCTIONS"."GETCUSTNAMEBYID": invalid identifier 错误。这两个文件在同一目录中,如何从 driver.sql
调用 functions.sql
中定义的函数?程序也可以这样调用吗?
driver.sql:
declare
name varchar2(30);
comm float;
commok boolean;
begin
select functions.getcustnamebyid(100)
into name
from dual;
dbms_output.put_line('Hi ' || name );
end;
/
你不知道。
一个函数是一个数据库对象;这意味着它已经 compiled on the database。在您可以使用这些函数之前,您首先需要编译它们 - 您可以通过执行来自 SQL*Plus 的 .sql 文件来执行此操作,例如:
sqlplus username/password@db @ driver.sql
这将在您的数据库中创建(或替换,如果它们已经存在)函数。
在每个函数创建后添加 SQL*Plus 命令 show errors
也是值得的,这样如果有任何错误您可以看到它们。
问题的根源在于函数调用
假设我们在模式 scott(标准示例模式)中创建函数 get_hello_world。
SCOTT@erp>
1 CREATE OR REPLACE FUNCTION get_hello_world RETURN VARCHAR2
2 IS
3 BEGIN
4 RETURN 'hello world';
5* END get_hello_world;
SCOTT@erp> /
Function created.
SCOTT@erp> commit;
接下来我们创建一个 driver.sql 文件。这是我的例子:
BEGIN
dbms_output.put_line(scott.get_hello_world);
END;
接下来,我们要在驱动文件中调用它:
SCOTT@erp> @driver.sql
4 /
hello world
PL/SQL procedure successfully completed.
虽然您的新对象 scott.get_hello_world
是函数类型的新数据库对象,但我们没有使用 "function".
这个词来限定我们的调用
您收到错误,PL/SQL: ORA-00904: "FUNCTIONS"."GETCUSTNAMEBYID": invalid identifier
,因为未正确引用 scott 架构中新编译的数据库对象,get_hello_world
。
最后,如果我们在使用 scott 数据库帐户时调用它,我们可以用所有者 scott
限定我们的调用。
在 PL/SQL 中,函数必须在您要使用它们的上下文中创建。通常这是通过在数据库中创建对象来完成的,正如其他答案所建议的那样。如果出于某种原因你真的反对创建数据库对象,你实际上可以将它们的范围限制在你的 PL/SQL 块中:
DECLARE
FUNCTION getcustnamebyid (id NUMBER)
RETURN VARCHAR2 IS
BEGIN
RETURN NULL;
END;
name VARCHAR2 (30);
BEGIN
name := getcustnamebyid (100);
DBMS_OUTPUT.put_line ('Hi ' || name);
END;
/
您不能以这种方式引用另一个文件中的函数,但它确实允许您使用这些函数而无需保留它们。这种方法的一个警告是您只能在过程代码中使用函数; SQL 只能引用创建为数据库对象的函数。
来晚了,但是您可以 "include" 包含一些函数的文件然后调用它们,例如,
helper_functions.sql
procedure Echo(AValue in varchar2) is
begin
dbms_output.put_line(AValue);
end;
driver.sql
set serveroutput on
declare
@@helper_functions.sql
begin
Echo('hello');
end;
/
这里的输出是
SQL> @@driver.sql
hello
PL/SQL procedure successfully completed.
我正在使用 SQL*Plus 并且有一个名为 functions.sql
的文件,其中包含 3 个 PL/SQL 函数:
create or replace function getcustnamebyid (id number) return varchar2(30)
is
...
begin
...
end;
/
create or replace function getspcommbyid (id number) return float
is
...
begin
...
/
create or replace function iscommok (comm float) return boolean
is
...
begin
...
end;
/
我正在尝试在 driver.sql
程序中调用这些函数。我尝试了以下操作,但出现 PL/SQL: ORA-00904: "FUNCTIONS"."GETCUSTNAMEBYID": invalid identifier 错误。这两个文件在同一目录中,如何从 driver.sql
调用 functions.sql
中定义的函数?程序也可以这样调用吗?
driver.sql:
declare
name varchar2(30);
comm float;
commok boolean;
begin
select functions.getcustnamebyid(100)
into name
from dual;
dbms_output.put_line('Hi ' || name );
end;
/
你不知道。
一个函数是一个数据库对象;这意味着它已经 compiled on the database。在您可以使用这些函数之前,您首先需要编译它们 - 您可以通过执行来自 SQL*Plus 的 .sql 文件来执行此操作,例如:
sqlplus username/password@db @ driver.sql
这将在您的数据库中创建(或替换,如果它们已经存在)函数。
在每个函数创建后添加 SQL*Plus 命令 show errors
也是值得的,这样如果有任何错误您可以看到它们。
问题的根源在于函数调用
假设我们在模式 scott(标准示例模式)中创建函数 get_hello_world。
SCOTT@erp>
1 CREATE OR REPLACE FUNCTION get_hello_world RETURN VARCHAR2
2 IS
3 BEGIN
4 RETURN 'hello world';
5* END get_hello_world;
SCOTT@erp> /
Function created.
SCOTT@erp> commit;
接下来我们创建一个 driver.sql 文件。这是我的例子:
BEGIN
dbms_output.put_line(scott.get_hello_world);
END;
接下来,我们要在驱动文件中调用它:
SCOTT@erp> @driver.sql
4 /
hello world
PL/SQL procedure successfully completed.
虽然您的新对象 scott.get_hello_world
是函数类型的新数据库对象,但我们没有使用 "function".
您收到错误,PL/SQL: ORA-00904: "FUNCTIONS"."GETCUSTNAMEBYID": invalid identifier
,因为未正确引用 scott 架构中新编译的数据库对象,get_hello_world
。
最后,如果我们在使用 scott 数据库帐户时调用它,我们可以用所有者 scott
限定我们的调用。
在 PL/SQL 中,函数必须在您要使用它们的上下文中创建。通常这是通过在数据库中创建对象来完成的,正如其他答案所建议的那样。如果出于某种原因你真的反对创建数据库对象,你实际上可以将它们的范围限制在你的 PL/SQL 块中:
DECLARE
FUNCTION getcustnamebyid (id NUMBER)
RETURN VARCHAR2 IS
BEGIN
RETURN NULL;
END;
name VARCHAR2 (30);
BEGIN
name := getcustnamebyid (100);
DBMS_OUTPUT.put_line ('Hi ' || name);
END;
/
您不能以这种方式引用另一个文件中的函数,但它确实允许您使用这些函数而无需保留它们。这种方法的一个警告是您只能在过程代码中使用函数; SQL 只能引用创建为数据库对象的函数。
来晚了,但是您可以 "include" 包含一些函数的文件然后调用它们,例如,
helper_functions.sql
procedure Echo(AValue in varchar2) is
begin
dbms_output.put_line(AValue);
end;
driver.sql
set serveroutput on
declare
@@helper_functions.sql
begin
Echo('hello');
end;
/
这里的输出是
SQL> @@driver.sql
hello
PL/SQL procedure successfully completed.