包体中有两个同名不同参数的函数是什么意思?
What does it means when there are two functions with the same name but different parameter in the package body?
在包规范中,函数名只出现一次,因此没有重载。在包体中,相同的函数名使用不同的参数集出现了两次。其中之一与包规范中的参数相同。我的问题是,包体中的 "first func" 是否真的被调用了?如果是,它到底在做什么?它正在尝试 return 本身。
--package specification
CREATE OR REPLACE
PACKAGE jtestpkg
IS
FUNCTION testfunc(p_num IN NUMBER, p_out1 IN out varchar2, p_out2 IN out varchar2)
RETURN NUMBER;
END jtestpkg;
--package body
CREATE OR REPLACE
PACKAGE BODY jtestpkg
IS
--first func
function testfunc
(p_num IN NUMBER,
p_out1 IN OUT varchar2)
return number is
v_out2 varchar2(50);
BEGIN
dbms_output.put_line('invoking first func');
RETURN testfunc(
p_num,
p_out1,
v_out2);
END;
--second func
FUNCTION testfunc(
p_num IN NUMBER,
p_out1 IN OUT varchar2,
p_out2 IN OUT varchar2)
RETURN NUMBER
IS
v_num number;
BEGIN
IF 1=p_num THEN
p_out1:='FirstOUT_1';
p_out2:='SecondOUT_1';
dbms_output.put_line(v_num||p_out1||p_out2);
RETURN 1;
elsif 2=p_num THEN
p_out1:='FirstOUT_2';
p_out2:='SecondOUT_2';
dbms_output.put_line(v_num||p_out1||p_out2);
RETURN 2;
ELSE
p_out1:='FirstOUT_3';
p_out2:='SecondOUT_3';
dbms_output.put_line(v_num||p_out1||p_out2);
return 3;
END IF;
------
p_out1:='FirstOUT_0';
p_out2:='SecondOUT_0';
dbms_output.put_line(v_num||p_out1||p_out2);
RETURN 0;
END testfunc;
END jtestpkg;
规范中声明的一个函数是public,可以从包外调用。在正文中定义但未在规范中声明的函数是私有的,只能从该包中调用。
在您的示例中,您标记为 'second func' 的包体中函数的第二个重载版本与规范中的声明相匹配,因此当您调用来自其他地方的功能:
declare
rc number;
in_out_1 varchar2(20) := 'A';
in_out_2 varchar2(20) := 'B';
begin
rc := jtestpkg.testfunc(42, in_out_1, in_out_2);
end;
/
FirstOUT_3SecondOUT_3
PL/SQL procedure successfully completed.
您标记为 'first func' 的主体中的第一个重载函数在规范中没有匹配的声明,因此您无法从外部调用它:
declare
rc number;
in_out_1 varchar2(20) := 'A';
begin
rc := jtestpkg.testfunc(42, in_out_1);
end;
/
ORA-06550: line 5, column 9:
PLS-00306: wrong number or types of arguments in call to 'TESTFUNC'
ORA-06550: line 5, column 3:
PL/SQL: Statement ignored
My question is, is the "first func" in the package body actually being invoked
没有。在您的代码中,'first func' 从未被调用。
It's trying to return itself.
不,不是。你的 'first func' 会调用 'second func' 如果它本身是从包内的其他地方调用的,但你目前没有这样做。
那里的调试说 'invoking first func' 但事实并非如此,它正在调用 second func,因为它进行的调用具有三个参数 - 匹配 'second func' 参数列表。 (这恰好是 public,但如果不是也没有关系,因为无论如何它都在包内部)。
举个例子,您可以调用私有函数作为 package instantiation and initialization:
的一部分
...
END testfunc;
-- initialization, called on instantiation (for each session)
BEGIN
dbms_output.put_line('Initialization start');
declare
rc number;
in_out_1 varchar2(20) := 'A';
begin
dbms_output.put_line('Initialization: calling first func');
rc := testfunc(1, in_out_1);
end;
dbms_output.put_line('Initialization end');
END jtestpkg;
/
然后在会话中第一次调用包中的任何东西 public 实例化它,初始化它,运行那个包级块。所以使用相同的匿名块:
declare
rc number;
in_out_1 varchar2(20) := 'A';
in_out_2 varchar2(20) := 'B';
begin
rc := jtestpkg.testfunc(42, in_out_1, in_out_2);
end;
/
你看(仅限第一次):
Initialization start
Initialization: calling first func
invoking first func
FirstOUT_1SecondOUT_1
Initialization end
FirstOUT_3SecondOUT_3
PL/SQL procedure successfully completed.
您仍然会看到与之前相同的 FirstOUT_3SecondOUT_3
输出,来自该调用中传递的值 42;但在此之前,您会看到 'first func' 的输出 FirstOUT_1SecondOUT_1
作为初始化过程的一部分调用 'second func' 并使用值 1。
允许函数调用自身,即递归调用,但每次都需要更改调用,否则会陷入无限循环,最终被杀死。不过你在这里也没有这样做。
在包规范中,函数名只出现一次,因此没有重载。在包体中,相同的函数名使用不同的参数集出现了两次。其中之一与包规范中的参数相同。我的问题是,包体中的 "first func" 是否真的被调用了?如果是,它到底在做什么?它正在尝试 return 本身。
--package specification
CREATE OR REPLACE
PACKAGE jtestpkg
IS
FUNCTION testfunc(p_num IN NUMBER, p_out1 IN out varchar2, p_out2 IN out varchar2)
RETURN NUMBER;
END jtestpkg;
--package body
CREATE OR REPLACE
PACKAGE BODY jtestpkg
IS
--first func
function testfunc
(p_num IN NUMBER,
p_out1 IN OUT varchar2)
return number is
v_out2 varchar2(50);
BEGIN
dbms_output.put_line('invoking first func');
RETURN testfunc(
p_num,
p_out1,
v_out2);
END;
--second func
FUNCTION testfunc(
p_num IN NUMBER,
p_out1 IN OUT varchar2,
p_out2 IN OUT varchar2)
RETURN NUMBER
IS
v_num number;
BEGIN
IF 1=p_num THEN
p_out1:='FirstOUT_1';
p_out2:='SecondOUT_1';
dbms_output.put_line(v_num||p_out1||p_out2);
RETURN 1;
elsif 2=p_num THEN
p_out1:='FirstOUT_2';
p_out2:='SecondOUT_2';
dbms_output.put_line(v_num||p_out1||p_out2);
RETURN 2;
ELSE
p_out1:='FirstOUT_3';
p_out2:='SecondOUT_3';
dbms_output.put_line(v_num||p_out1||p_out2);
return 3;
END IF;
------
p_out1:='FirstOUT_0';
p_out2:='SecondOUT_0';
dbms_output.put_line(v_num||p_out1||p_out2);
RETURN 0;
END testfunc;
END jtestpkg;
规范中声明的一个函数是public,可以从包外调用。在正文中定义但未在规范中声明的函数是私有的,只能从该包中调用。
在您的示例中,您标记为 'second func' 的包体中函数的第二个重载版本与规范中的声明相匹配,因此当您调用来自其他地方的功能:
declare
rc number;
in_out_1 varchar2(20) := 'A';
in_out_2 varchar2(20) := 'B';
begin
rc := jtestpkg.testfunc(42, in_out_1, in_out_2);
end;
/
FirstOUT_3SecondOUT_3
PL/SQL procedure successfully completed.
您标记为 'first func' 的主体中的第一个重载函数在规范中没有匹配的声明,因此您无法从外部调用它:
declare
rc number;
in_out_1 varchar2(20) := 'A';
begin
rc := jtestpkg.testfunc(42, in_out_1);
end;
/
ORA-06550: line 5, column 9:
PLS-00306: wrong number or types of arguments in call to 'TESTFUNC'
ORA-06550: line 5, column 3:
PL/SQL: Statement ignored
My question is, is the "first func" in the package body actually being invoked
没有。在您的代码中,'first func' 从未被调用。
It's trying to return itself.
不,不是。你的 'first func' 会调用 'second func' 如果它本身是从包内的其他地方调用的,但你目前没有这样做。
那里的调试说 'invoking first func' 但事实并非如此,它正在调用 second func,因为它进行的调用具有三个参数 - 匹配 'second func' 参数列表。 (这恰好是 public,但如果不是也没有关系,因为无论如何它都在包内部)。
举个例子,您可以调用私有函数作为 package instantiation and initialization:
的一部分...
END testfunc;
-- initialization, called on instantiation (for each session)
BEGIN
dbms_output.put_line('Initialization start');
declare
rc number;
in_out_1 varchar2(20) := 'A';
begin
dbms_output.put_line('Initialization: calling first func');
rc := testfunc(1, in_out_1);
end;
dbms_output.put_line('Initialization end');
END jtestpkg;
/
然后在会话中第一次调用包中的任何东西 public 实例化它,初始化它,运行那个包级块。所以使用相同的匿名块:
declare
rc number;
in_out_1 varchar2(20) := 'A';
in_out_2 varchar2(20) := 'B';
begin
rc := jtestpkg.testfunc(42, in_out_1, in_out_2);
end;
/
你看(仅限第一次):
Initialization start
Initialization: calling first func
invoking first func
FirstOUT_1SecondOUT_1
Initialization end
FirstOUT_3SecondOUT_3
PL/SQL procedure successfully completed.
您仍然会看到与之前相同的 FirstOUT_3SecondOUT_3
输出,来自该调用中传递的值 42;但在此之前,您会看到 'first func' 的输出 FirstOUT_1SecondOUT_1
作为初始化过程的一部分调用 'second func' 并使用值 1。
允许函数调用自身,即递归调用,但每次都需要更改调用,否则会陷入无限循环,最终被杀死。不过你在这里也没有这样做。