在Oracle包中如何定义默认值

12
当您在Oracle中定义包时,有一个类似标题的部分和一个主体部分。必须在这两个位置中定义所有参数。我想使调用程序(IBM消息代理)中的某个参数成为可选项。我需要在标题和主体定义中都添加默认值吗?
此外,有人能否确认是否可以在不为具有默认值的参数指定任何值的情况下,使用消息代理调用该过程?
谢谢!
更新:我注意到我可以将默认值添加到标题而不是主体,或者可以将其添加到两者之间。我不能只将其添加到主体中。
将它们添加到两种位置和仅添加到标题之间有什么区别?
更新:
我可以在规范中仅指定默认值而不指定主体。或者也可以在两个位置同时指定默认值。有什么区别?
create or replace
package myPackage is
PROCEDURE myProc  (
    parm1 IN varchar2,                           
    parm1 IN date,                     
    parm1 IN number default null
);
end myPackage;

create or replace
package body myPackage is
PROCEDURE myProc  (
    parm1 IN varchar2,                           
    parm1 IN date,                     
    parm1 IN number
) is
...
...
...
end myProc;
end myPackage;

TSQL 是特定于微软的。您可能需要修改该标签。 - paparazzo
啊,你说得对...我可能是一厢情愿了 :) - kralco626
2个回答

14
如果你想将参数设置为可选,则必须指定默认值。如果默认值没有在主体声明中,我会感到惊讶它是否能正常工作。
我已经养成了让包规格说明与包体声明完全相同的习惯,以避免出现问题。
编辑:
正如OP所指出的,它可以只在规格说明中,并且它能够工作。如果它在主体中但不在规格说明中,则会产生错误:
SQL> CREATE OR REPLACE PACKAGE p AS
  2  PROCEDURE prc(p1 VARCHAR2, p2 VARCHAR2);
  3  END;
  4  /

Package created
SQL> CREATE OR REPLACE PACKAGE BODY p AS
  2  PROCEDURE prc(p1 VARCHAR2 DEFAULT 'P1', p2 VARCHAR2)
  3  IS
  4  BEGIN
  5    dbms_output.put_line(p1||','||p2);
  6  END;
  7  END;
  8  /

Warning: Package body created with compilation errors
SQL>

但如果只在规范中,所有的都可以:

SQL> CREATE OR REPLACE PACKAGE p AS
  2  PROCEDURE prc(p1 VARCHAR2 DEFAULT 'P1Dflt', p2 VARCHAR2);
  3  END;
  4  /

Package created
SQL> CREATE OR REPLACE PACKAGE BODY p AS
  2  PROCEDURE prc(p1 VARCHAR2, p2 VARCHAR2)
  3  IS
  4  BEGIN
  5    dbms_output.put_line(p1||','||p2);
  6  END;
  7  END;
  8  /

Package body created
SQL> DECLARE
  2  BEGIN
  3    p.prc(p2=>'Test');
  4  END;
  5  /

P1Dflt,Test

PL/SQL procedure successfully completed

SQL> 

话虽如此,对于“有什么区别”的问题,似乎将默认值只放在规范中还是两个地方都放并没有区别 - 最终结果是相同的。我认为出于文档目的应该在两个地方都放上默认值。


惊喜!哈哈。你肯定可以在规范中设置默认值,而不是在主体中设置。有人知道这样做与两个地方都设置有什么区别吗? - kralco626
确切的翻译:我的问题是,这会有区别吗? - kralco626
1
@kralco626 这并没有什么区别;但是考虑到以后调试这段代码和其他人来查看它。如果明显知道发生了什么,并且默认值在规范和主体中,那么这将使每个人的生活更加轻松。 - Ben
@DCookie,一个在规范中没有声明的函数,在包体中可以有默认值吗? - Ben
@kralco626,请看我的回答更新。这没有任何区别。 - DCookie
显示剩余2条评论

1
在包中,您可以在规范或正文中设置默认变量/常量。个人而言,我会将它们放在正文中,因为我不需要查看规范就能知道发生了什么;但我知道正式的 Oracle 与我不同意。在正文中,这应该直接放在 create or replace 下面。
不过,您使用的 "parameter" 这个词有一点让人困惑,这暗示您正在将其传递给包中的函数/过程。如果您在包规范或正文中设置了全局变量,则根本无需将其传递给其他任何地方。如果您更改了全局变量,那么您会带来一大堆麻烦,或者会留下一个问题供后来者解决。
如果您只是在单个函数/过程中使用它,则将其设置在该特定元素的声明中即可。 这篇文章 可以帮助您更好地理解。

啊,如果是这样的话,@DCookie是对的;一定要在两个地方都放置它,以避免许多麻烦。 - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接