Oracle包中的全局变量大小

时间:2013-04-12 10:13:26

标签: oracle package global-variables

如何根据函数中的参数大小设置oracle包中Varchar2类型的全局变量的大小。

CREATE OR REPLACE PACKAGE Test 
AS

   g_lastname Varchar2(15);
   FUNCTION search( p_lastname IN varchar2);

END;

CREATE OR REPLACE PACKAGE BODY Test
AS
    FUNCTION search(p_lastname IN VARCHAR2) return VARCHAR2 
    IS
    BEGIN
        g_lastname := p_lastname;
        return g_lastname;
    END;
END;

这里的问题是如果p_lastname大小超过15,那么它将给出错误。

2 个答案:

答案 0 :(得分:1)

您不能,因为函数参数可以是varchar2的任何大小,并且在运行时才会知道。

如果你知道以后如何使用该值,那么你可以根据表列来约束它;因此,如果它最终将用于表people中的选择,您可以将其声明为:

    g_lastname people.last_name%type;

您还可以在函数声明中使用该语法:

    FUNCTION search(p_lastname IN people.last_name%type) return VARCHAR2

...虽然这实际上并没有限制可以传入的值的大小;如果p_lastname的值太大,分配仍然会失败。可以说,在这种情况下,它必须在某些时候失败,并且它可能比稍后尝试在select中使用它时更好。但它在代码中提供了一些一致性,(IMO)显示了全局和参数的意图,这对于以后的维护和故障排除很有用。

如果您只想避免错误,可以选择截断传递的值,如果它太长:

        g_lastname := substr(p_lastname, 1, 15);

...或首先测试长度,但幻数并不完全理想(如果你改变g_lastname的定义,你必须记住找到并替换任何依赖于那个长度的东西);或者抓住并做一些例外情况。

否则,宣布它比你想象的还要大,没有多少缺点,最多可达:

    g_lastname varchar2(32767);

虽然你可能想出一个真实的较小的最大长度值,但是当有人改变要求时,当然! documentation讨论了大变量的内存分配。

答案 1 :(得分:1)

  

“%type对我的情况没有帮助。”

这很不寻常。 PL / SQL程序之间传递的大多数数据来自或最终存在于数据库表中。因此,最佳实践是通过引用相应列的声明来定义变量和参数。

但是,对于真正未映射到任何表列的数据项,存在子类型声明。您可以在任何地方定义这些,但在一个地方组织所有声明很有帮助:

create or replace package types as
    subtype name_t is varchar2(15);
end;
/

你可以在你的程序中使用它:

CREATE OR REPLACE PACKAGE Test 
AS

   FUNCTION search( p_lastname IN types.name_t) return types.name_t;

END;

(我将g_lastname从规范移到了正文,因为最好将包变量封装在正文中,并且只能通过打包的程序访问它们。)

CREATE OR REPLACE PACKAGE BODY Test
AS

    g_lastname types.name_t;

    FUNCTION search( p_lastname IN types.name_t) return types.name_t 
    IS
    BEGIN
        g_lastname := p_lastname;
        return g_lastname;
    END;
END;

使用子类型的优点是只有一个位置可以定义类型的精度。如果您需要包含20个字符的名称,只需更改该包规范中的声明,并将更改传播到所有引用程序。