与此调用匹配的构造声明过多
too many declaration of a construct match this call
我已经声明了一个带有两个参数的构造函数的对象。我不能使用它,因为 oracle returns:
[Error] Execution (2: 10): ORA-06553: PLS-307: too many declarations
of 'BOUNDARY' match this call
这个构造函数我只声明过一次。
我的代码可以在 db fiddle 上运行,但不能在我的数据库上运行。 dbfiddle 上的代码和我的代码之间的唯一区别是这个对象有一个所有者。
因此对象的名称是这样定义的:owner_name.object_name
.
我检查过对象是否在另一个所有者中定义。当我调用构造函数时,我使用 owner_name.constructor
.
我创建了一个带有 0 个参数的虚拟构造函数并且它有效。
_
CREATE OR REPLACE TYPE my_user.boundary AS OBJECT
(
v_start INTEGER,
v_end INTEGER,
CONSTRUCTOR FUNCTION boundary (i_start INTEGER, i_end INTEGER)
RETURN SELF AS RESULT,
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
);
CREATE OR REPLACE TYPE BODY my_user.boundary
AS
CONSTRUCTOR FUNCTION boundary
RETURN SELF AS RESULT
IS
BEGIN
v_start := 1;
v_end := 2;
RETURN;
END;
CONSTRUCTOR FUNCTION boundary (i_start INTEGER, i_end INTEGER)
RETURN SELF AS RESULT
IS
BEGIN
v_start := i_start;
v_end := i_end;
RETURN;
END;
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
IS
BEGIN
IF v_start <= i AND i <= v_end
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
END;
SELECT ( my_user.boundary(1,2)) FROM DUAL; --doesn't work
[Error] Execution (2: 10): ORA-06553: PLS-307: too many declarations of 'BOUNDARY' match this call
SELECT ( my_user.boundary()).isInside(1) FROM DUAL; --is working
1
在我将未声明的构造函数添加到规范后,它编译并运行良好:
CREATE OR REPLACE TYPE BV_OWN.boundary AS OBJECT
(
v_start INTEGER,
v_end INTEGER,
CONSTRUCTOR FUNCTION boundary -- added
RETURN SELF AS RESULT,
CONSTRUCTOR FUNCTION boundary (i_start INTEGER, i_end INTEGER)
RETURN SELF AS RESULT,
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
);
不得不放弃模式规范,因为我没有 BV_OWN 用户来测试。使用 Oracle 21c。 db<>fiddle here
当 运行 under Oracle 21c, but not under 18c 或 11g 时,您的代码在 db<>fiddle 中有效。
你说你没有多次声明构造函数,但你有点有;有一个具有相同参数的默认构造函数 - from the 19c doc:
The database implicitly defines a constructor method for each user-defined type that you create. A constructor is a system-supplied procedure that is used in SQL statements or in PL/SQL code to construct an instance of the type value. The name of the constructor method is the name of the user-defined type. You can also create a user-defined constructor using the constructor_spec syntax.
and:
By default, the system implicitly defines a constructor function for all object types that have attributes.
A system-defined constructor is sometimes known as the attribute value constructor.
您正在创建一个 user-defined 构造函数,但它与隐式构造函数具有相同的定义。嗯,差不多。
19c also says:
a user-defined constructor does hide, and thus supersede, the attribute-value constructor for its type if the signature of the user-defined constructor exactly matches the signature of the attribute-value constructor.
For the signatures to match, the names and types of the parameters (after the implicit SELF parameter) of the user-defined constructor must be the same as the names and types of the attributes of the type.
在 18c 中 it works 如果更改参数 names 以匹配属性名称:
CREATE OR REPLACE TYPE boundary AS OBJECT
(
v_start INTEGER,
v_end INTEGER,
CONSTRUCTOR FUNCTION boundary (v_start INTEGER, v_end INTEGER)
RETURN SELF AS RESULT,
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
);
/
CREATE OR REPLACE TYPE BODY boundary
AS
CONSTRUCTOR FUNCTION boundary (v_start INTEGER, v_end INTEGER)
RETURN SELF AS RESULT
IS
BEGIN
SELF.v_start := v_start;
SELF.v_end := v_end;
RETURN;
END;
...
21c 似乎更 forgiving/flexible,尽管文档 hasn't changed。 (或者也许 19c 或它的某些版本也允许这样做 - 我只是继续 db<>fiddle..)
中的可用版本
但是,由于您在这里所做的只是一个简单的赋值,您不需要任何版本的重写构造函数 - it works without it。
我已经声明了一个带有两个参数的构造函数的对象。我不能使用它,因为 oracle returns:
[Error] Execution (2: 10): ORA-06553: PLS-307: too many declarations of 'BOUNDARY' match this call
这个构造函数我只声明过一次。
我的代码可以在 db fiddle 上运行,但不能在我的数据库上运行。 dbfiddle 上的代码和我的代码之间的唯一区别是这个对象有一个所有者。
因此对象的名称是这样定义的:
owner_name.object_name
.我检查过对象是否在另一个所有者中定义。当我调用构造函数时,我使用
owner_name.constructor
.我创建了一个带有 0 个参数的虚拟构造函数并且它有效。
_
CREATE OR REPLACE TYPE my_user.boundary AS OBJECT
(
v_start INTEGER,
v_end INTEGER,
CONSTRUCTOR FUNCTION boundary (i_start INTEGER, i_end INTEGER)
RETURN SELF AS RESULT,
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
);
CREATE OR REPLACE TYPE BODY my_user.boundary
AS
CONSTRUCTOR FUNCTION boundary
RETURN SELF AS RESULT
IS
BEGIN
v_start := 1;
v_end := 2;
RETURN;
END;
CONSTRUCTOR FUNCTION boundary (i_start INTEGER, i_end INTEGER)
RETURN SELF AS RESULT
IS
BEGIN
v_start := i_start;
v_end := i_end;
RETURN;
END;
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
IS
BEGIN
IF v_start <= i AND i <= v_end
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
END;
SELECT ( my_user.boundary(1,2)) FROM DUAL; --doesn't work
[Error] Execution (2: 10): ORA-06553: PLS-307: too many declarations of 'BOUNDARY' match this call
SELECT ( my_user.boundary()).isInside(1) FROM DUAL; --is working
1
在我将未声明的构造函数添加到规范后,它编译并运行良好:
CREATE OR REPLACE TYPE BV_OWN.boundary AS OBJECT
(
v_start INTEGER,
v_end INTEGER,
CONSTRUCTOR FUNCTION boundary -- added
RETURN SELF AS RESULT,
CONSTRUCTOR FUNCTION boundary (i_start INTEGER, i_end INTEGER)
RETURN SELF AS RESULT,
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
);
不得不放弃模式规范,因为我没有 BV_OWN 用户来测试。使用 Oracle 21c。 db<>fiddle here
当 运行 under Oracle 21c, but not under 18c 或 11g 时,您的代码在 db<>fiddle 中有效。
你说你没有多次声明构造函数,但你有点有;有一个具有相同参数的默认构造函数 - from the 19c doc:
The database implicitly defines a constructor method for each user-defined type that you create. A constructor is a system-supplied procedure that is used in SQL statements or in PL/SQL code to construct an instance of the type value. The name of the constructor method is the name of the user-defined type. You can also create a user-defined constructor using the constructor_spec syntax.
and:
By default, the system implicitly defines a constructor function for all object types that have attributes.
A system-defined constructor is sometimes known as the attribute value constructor.
您正在创建一个 user-defined 构造函数,但它与隐式构造函数具有相同的定义。嗯,差不多。
19c also says:
a user-defined constructor does hide, and thus supersede, the attribute-value constructor for its type if the signature of the user-defined constructor exactly matches the signature of the attribute-value constructor.
For the signatures to match, the names and types of the parameters (after the implicit SELF parameter) of the user-defined constructor must be the same as the names and types of the attributes of the type.
在 18c 中 it works 如果更改参数 names 以匹配属性名称:
CREATE OR REPLACE TYPE boundary AS OBJECT
(
v_start INTEGER,
v_end INTEGER,
CONSTRUCTOR FUNCTION boundary (v_start INTEGER, v_end INTEGER)
RETURN SELF AS RESULT,
MEMBER FUNCTION isInside (i INTEGER)
RETURN INTEGER
);
/
CREATE OR REPLACE TYPE BODY boundary
AS
CONSTRUCTOR FUNCTION boundary (v_start INTEGER, v_end INTEGER)
RETURN SELF AS RESULT
IS
BEGIN
SELF.v_start := v_start;
SELF.v_end := v_end;
RETURN;
END;
...
21c 似乎更 forgiving/flexible,尽管文档 hasn't changed。 (或者也许 19c 或它的某些版本也允许这样做 - 我只是继续 db<>fiddle..)
中的可用版本但是,由于您在这里所做的只是一个简单的赋值,您不需要任何版本的重写构造函数 - it works without it。