管理 pl/sql procedures/functions 的版本
Managing version of pl/sql procedures/functions
我正在寻找支持多个版本 procedures/functions 的最佳实践。
例如,我有一个程序使用 oracle apex 包生成复杂的 json 输出,应用程序使用它来绘制一些前端。
现在需要 return 不同的输出结构保持相同的入口点。
我看到几个选项:
- 使用 if 语句在代码版本之间包含版本参数和路由 - 这会使代码变得混乱
- 包含版本参数并在包内创建多个版本的程序 - 代码重复,后果已知
- 包括版本参数并创建多个版本包 - 更多重复
我检查了一些 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 模式以防止代码重复。
...但不幸的是,在不了解更多细节的情况下,我无法确定这种方法是否适用于您的用例。
我正在寻找支持多个版本 procedures/functions 的最佳实践。 例如,我有一个程序使用 oracle apex 包生成复杂的 json 输出,应用程序使用它来绘制一些前端。
现在需要 return 不同的输出结构保持相同的入口点。
我看到几个选项:
- 使用 if 语句在代码版本之间包含版本参数和路由 - 这会使代码变得混乱
- 包含版本参数并在包内创建多个版本的程序 - 代码重复,后果已知
- 包括版本参数并创建多个版本包 - 更多重复
我检查了一些 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 模式以防止代码重复。
...但不幸的是,在不了解更多细节的情况下,我无法确定这种方法是否适用于您的用例。