这是我写的存储过程。在这个过程中,“p_subjectid”是从前端传递的数字数组。
PROCEDURE getsubjects(p_subjectid subjectid_tab,p_subjects out refCursor)
as
BEGIN
open p_subjects for select * from empsubject where subject_id in
(select column_value from table(p_subjectid));
--select * from table(cast(p_subjectid as packg.subjectid_tab))
END getsubjects;
这是我得到的错误。
Oracle error ORA-22905: cannot access rows from a non-nested table item OR
正如我在不同的帖子中看到的那样,我尝试在下面的评论中给出表格函数中的“cast(p_subjectid as packg.subjectid_tab)”。但是我收到了另一个错误:ORA-00902: invalid datatype
。
这是“subjectid_tab”的定义。
type subjectid_tab is table of number index by binary_integer;
任何人都可以告诉我错误是什么。我的程序有什么问题。
答案 0 :(得分:11)
您必须在ammoQ建议的“数据库级别”声明类型:
CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer;
而不是在PL / SQL中声明类型。如果在PL / SQL块中声明类型,它将无法用于SQL“引擎”。
答案 1 :(得分:2)
我昨天刚遇到这个问题。
DECLARE TYPE number_table IS TABLE OF NUMBER; result_ids number_table := number_table(); BEGIN /* .. bunch of code that uses my type successfully */ OPEN ? AS SELECT * FROM TABLE(CAST(result_ids AS number_table)); /* BOOM! */ END;
从java例程调用时,前面描述的两种方法都失败了。我发现这是因为类型number_table没有以可导出的方式定义,而不是从数据库中运出。该类型在常规内部工作得很好。但是,只要您尝试执行以任何方式引用它的可返回记录集(包括IN子句?!?),您将获得未定义的数据类型。
所以解决方案确实是CREATE TYPE myschema.number_table IS TABLE OF NUMBER;
然后从块中删除类型声明并使用模式级声明。使用模式限定符来引用类型,以确保使用正确的类型。
答案 2 :(得分:2)
这是一个很好的解决方案。 如果您转换的类型位于pl / sql块的DECLARE部分,则不能使用表(cast())。 你真的需要使用CREATE TYPE my_type [...]。否则,它将抛出“无法获取行[...]”异常。
答案 3 :(得分:1)
您必须转换流水线查询的结果:
如果您的流水线函数返回varchar2的行类型,则定义一个类型(例如)
CREATE OR REPLACE TYPE char_array_t is VARRAY(32) of varchar2(255);
select * from table(cast(fn(x) as user_type_t ) );
现在可以使用了。
答案 4 :(得分:1)
Oracle有两个执行范围:SQL和PL / SQL。当您使用SELECT
/ INSERT
/ UPDATE
(etc)语句时,您正在SQL范围内工作,并且在Oracle 11g及更低版本中,您不能引用PL中定义的类型/ SQL范围。 (注意:Oracle 12对此进行了更改,因此您可以引用PL / SQL类型。)
TYPE subjectid_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
是一个关联数组,只能在PL / SQL范围内定义,因此不能在SQL语句中使用。
您想要的是使用以下方法在SQL范围中定义集合(而不是关联数组):
CREATE TYPE subjectid_tab IS TABLE OF NUMBER;
(注意:您不需要集合的INDEX BY
子句。)
然后你可以这样做:
OPEN p_subjects FOR
SELECT *
FROM empsubject
WHERE subject_id MEMBER OF p_subjectid;
或
OPEN p_subjects FOR
SELECT *
FROM empsubject
WHERE subject_id IN ( SELECT COLUMN_VALUE FROM TABLE( p_subjectid ) );