代码之家  ›  专栏  ›  技术社区  ›  Dracontis M2je

PLS-00307或参数顺序是否重要?

  •  0
  • Dracontis M2je  · 技术社区  · 8 年前

    我无法理解Oracle DBMS的这种行为。我给出了两个创建PL/SQL类型的示例。第一个是:

    create or replace type TEST_TYPE as object (
        ID                      CHAR(36),
        NAME                    VARCHAR2(117 CHAR),
        IS_DEFAULT              CHAR(1),
        APPLICATION_ORDER       NUMBER(38,0),
        CONSTRUCTOR FUNCTION TEST_TYPE(
            ID                      VARCHAR2,
            NAME                    VARCHAR2,
            APPLICATION_ORDER       NUMBER default 0,
            IS_DEFAULT              VARCHAR2 default 'N'
        ) RETURN SELF AS RESULT
    );
    
    CREATE OR REPLACE TYPE BODY TEST_TYPE IS
    CONSTRUCTOR FUNCTION TEST_TYPE(
            ID                  VARCHAR2,
            NAME                VARCHAR2,
            APPLICATION_ORDER   NUMBER default 0,
            IS_DEFAULT          VARCHAR2 default 'N'
        ) RETURN SELF AS RESULT IS
        BEGIN
            SELF.ID                  := ID;
            SELF.NAME                := NAME;
            SELF.IS_DEFAULT          := IS_DEFAULT;
            SELF.APPLICATION_ORDER   := APPLICATION_ORDER;
    
            RETURN;
        END;
    END;
    
    declare
       app TEST_TYPE;
    begin
        app := TEST_TYPE(
            '00000000-0000-0000-0000-000000000000'
            ,'APP_NAME'
            ,13
            ,'N'
        );
    end;
    

    create or replace type TEST_TYPE as object (
        ID                      CHAR(36),
        NAME                    VARCHAR2(117 CHAR),
        IS_DEFAULT              CHAR(1),
        APPLICATION_ORDER       NUMBER(38,0),
        CONSTRUCTOR FUNCTION TEST_TYPE(
            ID                      VARCHAR2,
            NAME                    VARCHAR2,
            IS_DEFAULT              VARCHAR2 default 'N',
            APPLICATION_ORDER       NUMBER default 0
        ) RETURN SELF AS RESULT
    );
    
    CREATE OR REPLACE TYPE BODY TEST_TYPE IS
    CONSTRUCTOR FUNCTION TEST_TYPE(
            ID                  VARCHAR2,
            NAME                VARCHAR2,
            IS_DEFAULT          VARCHAR2 default 'N',
            APPLICATION_ORDER   NUMBER default 0
        ) RETURN SELF AS RESULT IS
        BEGIN
            SELF.ID                  := ID;
            SELF.NAME                := NAME;
            SELF.IS_DEFAULT          := IS_DEFAULT;
            SELF.APPLICATION_ORDER   := APPLICATION_ORDER;
    
            RETURN;
        END;
    END;
    
    declare
       app TEST_TYPE;
    begin
        app := TEST_TYPE(
            '00000000-0000-0000-0000-000000000000'
            ,'APP_NAME'
            ,'N'
            ,13
        );
    end;
    

    1 回复  |  直到 8 年前
        1
  •  1
  •   Alex Poole    8 年前

    问题是,您正在创建自己的构造函数,其签名与 the default constructor

    数据库为您创建的每个用户定义类型隐式定义了一个构造函数方法。构造函数是系统提供的过程,在SQL语句或PL/SQL代码中用于构造类型值的实例。构造函数方法的名称是用户定义类型的名称。还可以使用 constructor\u规范 语法。

    这也称为 the attribute-value constructor

    您的代码在不定义自己的构造函数的情况下工作:

    create or replace type TEST_TYPE as object (
        ID                      CHAR(36),
        NAME                    VARCHAR2(117 CHAR),
        IS_DEFAULT              CHAR(1),
        APPLICATION_ORDER       NUMBER(38,0)
    );
    /
    
    Type TEST_TYPE compiled
    
    declare
       app TEST_TYPE;
    begin
        app := TEST_TYPE(
            '00000000-0000-0000-0000-000000000000'
            ,'APP_NAME'
            ,'N'
            ,13
        );
    end;
    /
    
    PL/SQL procedure successfully completed.
    

    ... 但不会拿起 default 如果使用更少的参数调用,则返回值。

    在第一个代码块中,您使用不同的签名定义自己的构造函数,因为参数(和数据类型)与默认值的顺序不同。当您使用该构造函数创建实例时,只有一个匹配,因为 number 值出现在列表或参数中。

    几乎

    重写(或隐藏)默认构造函数, but the signature has to match exactly

    [...] 然而,如果用户定义构造函数的签名与属性值构造函数的签名完全匹配,则用户定义构造函数确实隐藏并因此取代其类型的属性值构造函数。对于要匹配的签名,参数的名称和类型(隐式 SELF 用户定义构造函数的参数)必须与类型的属性的名称和类型相同。参数的模式(隐式 用户定义构造函数的参数)必须为 IN

    char 而不是 varchar2

    create or replace type TEST_TYPE as object (
        ID                      CHAR(36),
        NAME                    VARCHAR2(117 CHAR),
        IS_DEFAULT              CHAR(1),
        APPLICATION_ORDER       NUMBER(38,0),
        CONSTRUCTOR FUNCTION TEST_TYPE(
            ID                      CHAR,
            NAME                    VARCHAR2,
            IS_DEFAULT              CHAR default 'N',
            APPLICATION_ORDER       NUMBER default 0
        ) RETURN SELF AS RESULT
    );
    /
    
    Type TEST_TYPE compiled
    
    CREATE OR REPLACE TYPE BODY TEST_TYPE IS
    CONSTRUCTOR FUNCTION TEST_TYPE(
            ID                  CHAR,
            NAME                VARCHAR2,
            IS_DEFAULT          CHAR default 'N',
            APPLICATION_ORDER   NUMBER default 0
        ) RETURN SELF AS RESULT IS
        BEGIN
            SELF.ID                  := ID;
            SELF.NAME                := NAME;
            SELF.IS_DEFAULT          := IS_DEFAULT;
            SELF.APPLICATION_ORDER   := APPLICATION_ORDER;
    
            RETURN;
        END;
    END;
    /
    
    Type Body TEST_TYPE compiled
    
    declare
       app TEST_TYPE;
    begin
        app := TEST_TYPE(
            '00000000-0000-0000-0000-000000000000'
            ,'APP_NAME'
            ,'N'
            ,13
        );
    end;
    /
    
    PL/SQL procedure successfully completed.
    

    现在,默认构造函数被用户定义的构造函数隐藏,因此没有混淆。