我正在使用 Oracle 的 RPC 签名依赖模式,并在更改同一类中过程的参数数据类型时遇到意外行为。根据 Oracle 文档,此类更改不应影响 RPC 签名,但它似乎会使相关过程失效。我希望从社区获得一些见解或解决方案。
这是我所做的:
将会话设置为签名依赖模式:
ALTER SESSION SET REMOTE_DEPENDENCIES_MODE = 'SIGNATURE';
创建了一个带有 NUMBER 参数的基本过程和一个调用该基本过程的依赖过程:
CREATE OR REPLACE PROCEDURE base_procedure (p_input IN NUMBER) IS
BEGIN
-- Procedure logic
END;
CREATE OR REPLACE PROCEDURE dependent_procedure IS
BEGIN
base_procedure(1); -- Calling the base procedure
-- Additional logic
END;
将基本过程的参数从
NUMBER
更改为 FLOAT
,预计不会失效,因为它们位于相同的数据类型类中:
CREATE OR REPLACE PROCEDURE base_procedure (p_input IN FLOAT) IS
BEGIN
-- Updated procedure logic
END;
这次更改后,依赖过程失效了,这与我对Oracle文档关于签名依赖模式的理解相矛盾。
有没有人经历过类似的行为,或者可以澄清为什么尽管数据类型更改在同一类中,但还是会发生这种失效?任何有关如何管理此类更改而不导致失效的见解将受到高度赞赏。
看起来确实很奇怪,但你在问题中说得对 - 程序无效(不是像状态所说的那样无效)。第一次执行后它将再次有效(假设验证发生时)。
SELECT object_name, object_type, status FROM all_objects WHERE OBJECT_NAME IN('BASE_PROCEDURE', 'DEPENDENT_PROCEDURE');
-- no rows selected
ALTER SESSION SET REMOTE_DEPENDENCIES_MODE = 'SIGNATURE';
-- Session altered.
CREATE OR REPLACE PROCEDURE base_procedure (p_input IN NUMBER) IS
BEGIN
dbms_output.put_line('base_procedure p_input = ' || p_input);
END;
-- Procedure BASE_PROCEDURE compiled
SELECT object_name, object_type, status FROM all_objects WHERE OBJECT_NAME IN('BASE_PROCEDURE', 'DEPENDENT_PROCEDURE');
-- OBJECT_NAME OBJECT_TYPE STATUS
-- ----------------- ----------------------- -------
-- BASE_PROCEDURE PROCEDURE VALID
CREATE OR REPLACE PROCEDURE dependent_procedure IS
BEGIN
dbms_output.put_line('dependent_procedure calling the base procedure NUMBER' );
base_procedure(1);
-- Additional logic
END;
-- Procedure DEPENDENT_PROCEDURE compiled
SELECT object_name, object_type, status FROM all_objects WHERE OBJECT_NAME IN('BASE_PROCEDURE', 'DEPENDENT_PROCEDURE');
-- OBJECT_NAME OBJECT_TYPE STATUS
-- ------------------- ----------------------- -------
-- BASE_PROCEDURE PROCEDURE VALID
-- DEPENDENT_PROCEDURE PROCEDURE VALID
通过依赖项“无效”更改基本程序结果:
CREATE OR REPLACE PROCEDURE base_procedure (p_input IN FLOAT) IS
BEGIN
dbms_output.put_line('base_procedure FLOAT p_input = ' || p_input);
END;
-- Procedure BASE_PROCEDURE compiled
SELECT object_name, object_type, status FROM all_objects WHERE OBJECT_NAME IN('BASE_PROCEDURE', 'DEPENDENT_PROCEDURE');
-- OBJECT_NAME OBJECT_TYPE STATUS
-- ------------------- ----------------------- -------
-- BASE_PROCEDURE PROCEDURE VALID
-- DEPENDENT_PROCEDURE PROCEDURE INVALID
现在,如果您运行该过程,它将像预期一样工作(或编译它)....
SET SERVEROUTPUT ON
BEGIN
dependent_procedure;
END;
/
-- dependent_procedure calling the base procedure NUMBER
-- base_procedure FLOAT p_input = 1
-- PL/SQL procedure successfully completed.
...并再次检查状态 - 一切正常。
SELECT object_name, object_type, status FROM all_objects WHERE OBJECT_NAME IN('BASE_PROCEDURE', 'DEPENDENT_PROCEDURE');
-- OBJECT_NAME OBJECT_TYPE STATUS
-- ------------------- ----------------------- -------
-- BASE_PROCEDURE PROCEDURE VALID
-- DEPENDENT_PROCEDURE PROCEDURE VALID