管理 pl/sql procedures/functions 的版本

Managing version of pl/sql procedures/functions

我正在寻找支持多个版本 procedures/functions 的最佳实践。 例如,我有一个程序使用 oracle apex 包生成复杂的 json 输出,应用程序使用它来绘制一些前端。

现在需要 return 不同的输出结构保持相同的入口点。

我看到几个选项:

我检查了一些 Oracle 机制,我唯一发现的是基于版本的重新定义 (EBR),但这不适合我。

鉴于您的标准“需要 return 不同的输出结构保持相同的入口点”,如果它们都必须同时可用,我相信最好的选择是有一个版本参数.如果这些将驻留在不同的模式或数据库中,您可以使用条件编译来仅编译适当的版本。

这是我使用带有版本参数的重载函数的示例。

CREATE OR REPLACE PACKAGE multiversion
    AUTHID DEFINER
AS
    FUNCTION boo (p_val IN VARCHAR2)
        RETURN VARCHAR2;

    FUNCTION boo (p_char IN VARCHAR2)
        RETURN VARCHAR2;


    FUNCTION boo (p_char2 IN VARCHAR2)
        RETURN VARCHAR2;

    FUNCTION boo (p_value IN VARCHAR2, p_version IN VARCHAR2)
        RETURN VARCHAR2;
END;

CREATE OR REPLACE PACKAGE BODY multiversion
AS
    FUNCTION boo (p_val IN VARCHAR2)
        RETURN VARCHAR2
    AS
    BEGIN
        RETURN 'p_val: ' || p_val;
    END boo;

    FUNCTION boo (p_char IN VARCHAR2)
        RETURN VARCHAR2
    AS
    BEGIN
        RETURN 'p_char: ' || p_char;
    END boo;

    FUNCTION boo (p_char2 IN VARCHAR2)
        RETURN VARCHAR2
    AS
    BEGIN
        RETURN 'p_char2: ' || p_char2 || ' ' || p_char2;
    END boo;

    FUNCTION boo (p_value IN VARCHAR2, p_version IN VARCHAR2)
        RETURN VARCHAR2
    AS
        l_ret   LONG;
    BEGIN
        l_ret   :=
            CASE p_version
                WHEN 'a' THEN boo (p_val => p_value)
                WHEN 'b' THEN boo (p_char => p_value)
                WHEN 'c' THEN boo (p_char2 => p_value)
            END;

        IF l_ret IS NULL
        THEN
            raise_application_error (
                -20000
              , COALESCE (p_version, '<<null>>') || ' is not a known version');
        END IF;

        RETURN l_ret;
    END boo;
END;

SELECT multiversion.boo (p_value => 'this is a test', p_version => 'c')
  FROM DUAL;

我不确定所需的隔离级别,还有一些额外的安全复杂性需要处理,但原则上可能的方法是为每个版本创建一个 Oracle 模式:

例如模式 v1,v2,v3,....vN

并将包版本存储在其关联的架构中,从而将该架构用作逻辑版本命名空间。

然后,为了在 mypackage 中引用 myproc 的示例版本 2,调用应用程序将请求:

v2.mypackage.myproc

要请求版本 N,调用应用程序将请求:

vN.mypackage.myproc

因此只需在调用中更改请求的架构前缀即可派生出所需的 mypackage.myproc 版本

公共组件可以存储在名为 common 的模式中,并共享给所有 v1..N 模式以防止代码重复。

...但不幸的是,在不了解更多细节的情况下,我无法确定这种方法是否适用于您的用例。