0

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

4

2 回答 2

1

你不能,因为函数参数可以是任意大小varchar2,直到运行时才知道。

如果您知道稍后将如何使用该值,那么您可以根据表格列对其进行约束;因此,如果最终将在 select from table 中使用它,则可以将其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);

尽管您可能会想出一个实际的较小的最大长度,但该值将永远需要(当然,直到有人更改要求!)。该文档讨论了大变量的内存分配。

于 2013-04-12T10:20:35.453 回答
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 个字符的名称,只需更改该包规范中的声明,更改就会传播到所有引用程序。

于 2013-04-13T22:05:45.513 回答