PLS-00306 关于使用 UDT 的 Oracle 函数
PLS-00306 on Oracle function using a UDT
我收到这个错误:
LINE/COL ERROR
-------- -----------------------------------------------------------------
13/3 PL/SQL: Statement ignored
13/13 PLS-00306: wrong number or types of arguments in call to 'JOIN_JT'
使用的类型:
CREATE TYPE join_t IS OBJECT (
inn NUMBER(38),
out NUMBER(38)
);
/
CREATE TYPE join_jt IS TABLE OF join_t;
/
这是返回错误的函数的 PL/SQL 代码。当我尝试将我在 join_table
中得到的结果传递给 retval
时,会触发上面的类型错误):
CREATE OR REPLACE FUNCTION join RETURN join_jt
AS
CURSOR cur_fv_table IS SELECT id,fv FROM london WHERE id <= 3000;
retval join_jt := join_jt ();
var_fv london.fv%type;
var_id london.id%type;
join_table join_jt := join_jt();
BEGIN
OPEN cur_fv_table;
LOOP
FETCH cur_fv_table INTO var_id,var_fv;
SELECT join_t(r.id, var_id) BULK COLLECT INTO join_table
FROM london r
WHERE manh_dist(r.fv,var_fv) <= 5;
retval.EXTEND;
retval := join_t(join_table);
END LOOP;
RETURN join_table;
END;
/
你可以使用这个函数来测试上面的功能:
CREATE OR REPLACE FUNCTION manh_dist(
fv1 LONDON.FV%TYPE,
fv2 LONDON.FV%TYPE
) RETURN NUMBER
AS
BEGIN
RETURN 0; -- Implement this.
END;
/
有谁知道如何解决这个错误?
我正在使用 Oracle 11g。
所以这是你的问题:
retval := join_t (join_table);
您正在尝试将 table 转换为对象类型。这是错误的。要填充输出 table,您需要将查询集合与 return 集合合并。 MULTISET UNION 是你所需要的:
CREATE OR REPLACE FUNCTION knn_join RETURN join_jt
IS
CURSOR cur_fv_table IS SELECT id,fv FROM londonfv WHERE id <= 3000;
retval join_jt := join_jt ();
var_fv londonfv.fv%type;
var_id londonfv.id%type;
join_table join_jt := join_jt();
BEGIN
OPEN cur_fv_table;
LOOP
FETCH cur_fv_table INTO var_id,var_fv;
SELECT join_t(r.id, var_id) BULK COLLECT
INTO join_table FROM londonfv r WHERE manhattan_dist(r.fv,var_fv) <=5;
retval := retval multiset union all join_table;
END LOOP;
RETURN retval;
END;
/
注意:我假设您真的想要 return 聚合集合 retval
而不是最后一个中间集合。
现在没有时间测试这个,我承认@Wernfried 让我怀疑这是否会 运行。如果您 运行 遇到问题,这种直截了当的方法会奏效:
for idx in join_table.first()..join_table.last()
loop
Retval.extend();
retval(retval.count()) := join_table(idx);
end loop;
您在存储结果时犯了错误。在线查看我的评论
retval := join_t (join_table);
CREATE OR REPLACE FUNCTION knn_join
RETURN join_jt
IS
CURSOR cur_fv_table
IS
SELECT id, fv
FROM londonfv
WHERE id <= 3000;
retval join_jt := join_jt ();
var_fv londonfv.fv%TYPE;
var_id londonfv.id%TYPE;
join_table join_jt := join_jt ();
BEGIN
OPEN cur_fv_table;
LOOP
--Fetching records of cursor to variable var_id & var_fv
FETCH cur_fv_table INTO var_id, var_fv;
SELECT join_t (r.id, r.fv) -- You made mistake here. You need to select your table columns here not any variable.
BULK COLLECT INTO join_table --- Populating the collection
FROM londonfv r
WHERE manhattan_dist (var_id, var_fv) <= 5; -- Checking from the function
--- Assuming there is only 1 record in collection join_table.
retval.EXTEND;
--- Storing the value of into the collection
retval := join_table;
/* If there are more then
for rec in 1..join_table.count
loop
retval.EXTEND;
retval(rec):= join_table(rec);
end loop;
*/
END LOOP;
RETURN retval;
END;
/
我收到这个错误:
LINE/COL ERROR
-------- -----------------------------------------------------------------
13/3 PL/SQL: Statement ignored
13/13 PLS-00306: wrong number or types of arguments in call to 'JOIN_JT'
使用的类型:
CREATE TYPE join_t IS OBJECT (
inn NUMBER(38),
out NUMBER(38)
);
/
CREATE TYPE join_jt IS TABLE OF join_t;
/
这是返回错误的函数的 PL/SQL 代码。当我尝试将我在 join_table
中得到的结果传递给 retval
时,会触发上面的类型错误):
CREATE OR REPLACE FUNCTION join RETURN join_jt
AS
CURSOR cur_fv_table IS SELECT id,fv FROM london WHERE id <= 3000;
retval join_jt := join_jt ();
var_fv london.fv%type;
var_id london.id%type;
join_table join_jt := join_jt();
BEGIN
OPEN cur_fv_table;
LOOP
FETCH cur_fv_table INTO var_id,var_fv;
SELECT join_t(r.id, var_id) BULK COLLECT INTO join_table
FROM london r
WHERE manh_dist(r.fv,var_fv) <= 5;
retval.EXTEND;
retval := join_t(join_table);
END LOOP;
RETURN join_table;
END;
/
你可以使用这个函数来测试上面的功能:
CREATE OR REPLACE FUNCTION manh_dist(
fv1 LONDON.FV%TYPE,
fv2 LONDON.FV%TYPE
) RETURN NUMBER
AS
BEGIN
RETURN 0; -- Implement this.
END;
/
有谁知道如何解决这个错误?
我正在使用 Oracle 11g。
所以这是你的问题:
retval := join_t (join_table);
您正在尝试将 table 转换为对象类型。这是错误的。要填充输出 table,您需要将查询集合与 return 集合合并。 MULTISET UNION 是你所需要的:
CREATE OR REPLACE FUNCTION knn_join RETURN join_jt
IS
CURSOR cur_fv_table IS SELECT id,fv FROM londonfv WHERE id <= 3000;
retval join_jt := join_jt ();
var_fv londonfv.fv%type;
var_id londonfv.id%type;
join_table join_jt := join_jt();
BEGIN
OPEN cur_fv_table;
LOOP
FETCH cur_fv_table INTO var_id,var_fv;
SELECT join_t(r.id, var_id) BULK COLLECT
INTO join_table FROM londonfv r WHERE manhattan_dist(r.fv,var_fv) <=5;
retval := retval multiset union all join_table;
END LOOP;
RETURN retval;
END;
/
注意:我假设您真的想要 return 聚合集合 retval
而不是最后一个中间集合。
现在没有时间测试这个,我承认@Wernfried 让我怀疑这是否会 运行。如果您 运行 遇到问题,这种直截了当的方法会奏效:
for idx in join_table.first()..join_table.last()
loop
Retval.extend();
retval(retval.count()) := join_table(idx);
end loop;
您在存储结果时犯了错误。在线查看我的评论
retval := join_t (join_table);
CREATE OR REPLACE FUNCTION knn_join
RETURN join_jt
IS
CURSOR cur_fv_table
IS
SELECT id, fv
FROM londonfv
WHERE id <= 3000;
retval join_jt := join_jt ();
var_fv londonfv.fv%TYPE;
var_id londonfv.id%TYPE;
join_table join_jt := join_jt ();
BEGIN
OPEN cur_fv_table;
LOOP
--Fetching records of cursor to variable var_id & var_fv
FETCH cur_fv_table INTO var_id, var_fv;
SELECT join_t (r.id, r.fv) -- You made mistake here. You need to select your table columns here not any variable.
BULK COLLECT INTO join_table --- Populating the collection
FROM londonfv r
WHERE manhattan_dist (var_id, var_fv) <= 5; -- Checking from the function
--- Assuming there is only 1 record in collection join_table.
retval.EXTEND;
--- Storing the value of into the collection
retval := join_table;
/* If there are more then
for rec in 1..join_table.count
loop
retval.EXTEND;
retval(rec):= join_table(rec);
end loop;
*/
END LOOP;
RETURN retval;
END;
/