为什么Oracle数据库的代码不起作用?

t2a7ltrp  于 2023-03-29  发布在  Oracle
关注(0)|答案(2)|浏览(220)

在我的例子中,函数PROCESS_OPERATORPROCESS_WHERE互相调用,但是这段代码编译时出错

CREATE OR REPLACE FUNCTION PROCESS_OPERATOR
(
  p_operator IN VARCHAR2
)
RETURN VARCHAR2
IS
  l_result VARCHAR2(100);
BEGIN
  l_result := PROCESS_WHERE('test');
  RETURN l_result;
END;
/
CREATE OR REPLACE FUNCTION PROCESS_WHERE
(
  p_where IN VARCHAR2
)
RETURN VARCHAR2
IS
  l_result VARCHAR2(100);
BEGIN
  l_result := PROCESS_OPERATOR('test');
  RETURN l_result;
END;

错误:

PLS-00905: object SYS.PROCESS_WHERE is invalid
PLS-00905: object SYS.PROCESS_OPERATOR is invalid

如何使函数相互调用?

sshcrbum

sshcrbum1#

1.我看到你以SYS用户的身份创建了你的对象。千万不要这样做:SYS模式是为Oracle的数据字典和其他内部程序保留的。它不应该包含自定义应用程序代码。创建一个单独的用户/模式来保存“您的”代码。
1.第一个函数无法编译是因为第二个函数还不存在。同样,第二个函数无法编译是因为第一个函数失败了,而且也不存在。要建立这种关系,你需要将你的函数嵌入到一个包中,这样所有的东西都可以同时编译。
1.也就是说,这个例子的目的是什么,因为它只会产生一个无限循环,并导致一个运行时错误或系统挂起,只要调用任何一个函数?

zhte4eai

zhte4eai2#

如果你想声明两个相互调用的函数,那么使用一个包:

CREATE PACKAGE package_name IS
  FUNCTION x(n IN NUMBER) RETURN NUMBER;
  FUNCTION y(n IN NUMBER) RETURN NUMBER;
END;
/

然后

CREATE PACKAGE BODY package_name IS
  FUNCTION x(n IN NUMBER) RETURN NUMBER
  IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('x: ' || n);
    RETURN CASE WHEN N > 0 THEN y(TRUNC(n/2)) ELSE 0 END;
  END;

  FUNCTION y(n IN NUMBER) RETURN NUMBER
  IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('y: ' || n);
    RETURN CASE WHEN N > 0 THEN x(n-1) ELSE 0 END;
  END;
END;
/

然后你可以调用它使用:

BEGIN
  DBMS_OUTPUT.PUT_LINE(PACKAGE_NAME.X(20));
END;
/

其输出:

x: 20
y: 10
x: 9
y: 4
x: 3
y: 1
x: 0
0

fiddle

相关问题