Oracle包中的全局变量大小

Oracle包中的全局变量大小,oracle,package,global-variables,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 VAR

如何根据函数中的参数大小设置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,那么它将给出错误。

您不能,因为函数参数可以是任何大小的
varchar2
,直到运行时才知道

如果知道以后将如何使用该值,则可以基于表列对其进行约束;因此,如果它最终将用于select from表
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);
虽然您可能会得出一个实际的较小的最大长度,但该值将永远需要(当然,直到有人更改要求!)。本文讨论了大变量的内存分配

“%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
从规范移到主体中,因为将包变量封装在主体中并仅通过打包过程访问它们是个好主意。)


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

声明具有最大大小的变量会浪费内存,不是吗?而且%type在我的情况下也没有帮助:(@eatSleepCode-不,不。如果你能找到一个你认为安全的限制,你可以设置一个更现实的限制,当然,但是你可以通过声明>=4000(字节)来节省内存。无论如何,我会保留%类型位,以防它对其他人有用…
将包测试创建或替换为g_lastname Varchar2(15);函数搜索(varchar2中的p_lastname);结束;创建或替换包体测试作为函数搜索(varchar2中的p_lastname)return VARCHAR2是BEGIN g_lastname:=p_lastname;return g_lastname;END;END;
这里我得到的是ORA-06502:PL/SQL:数值或值错误:字符串缓冲区太小,为g_lastname赋值时异常,实际上p_lastname的大小是1字节。@APC我在为va赋值时对这个问题有疑问p_lastname到g_lastname的lue它给了我ORA-06502:PL/SQL:数值或值错误:字符串缓冲区太小,作为错误。这应该是什么原因,这里p_lastname的大小是varchar2(1)。谢谢。
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;