Oracle PL/SQL中能否直接用函数返回值作为IN子句的列表?
问题描述
我有如下Oracle函数:
FUNCTION get_ids_by_acct(acct_p NUMBER) RETURN SYS.ODCINUMBERLIST IS CURSOR cli_cur IS SELECT id FROM test_clients WHERE account = acct_p; ids_n SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST(); cnt_n NUMBER := 0; BEGIN FOR cli IN cli_cur LOOP ids_n.EXTEND; ids_n(ids_n.COUNT) := cli.id; cnt_n := cnt_n + 1; END LOOP; IF cnt_n = 0 THEN ids_n.EXTEND; ids_n(conts_n.COUNT) := -1; END IF; RETURN ids_n; END;
目前该函数通过以下方式调用可以正常工作:
SELECT * FROM test_clients WHERE id IN (SELECT * FROM TABLE(get_ids_by_acct(1)));
但我希望用更简洁的方式实现相同效果,直接这样写是否可行?
SELECT * FROM test_clients WHERE id IN (get_ids_by_acct(1));
解答
直接用 id IN (get_ids_by_acct(1)) 这种写法不可行。
原因是:IN 子句要求括号内是单个值、逗号分隔的值列表,或者返回单列结果的子查询。而 get_ids_by_acct 返回的是 SYS.ODCINUMBERLIST 类型的集合,Oracle无法直接将集合类型当作 IN 子句的输入,必须通过 TABLE() 函数将集合转换为关系型结果集,再用子查询的方式传入 IN 子句。
如果想要简化写法,可以考虑以下替代方案:
- 改用
MEMBER OF操作符,语法更简洁:
SELECT * FROM test_clients WHERE id MEMBER OF get_ids_by_acct(1);
- 另外注意原函数存在笔误:
ids_n(conts_n.COUNT)应该改为ids_n(ids_n.COUNT),否则运行时会抛出未定义标识符的错误。
内容的提问来源于stack exchange,提问作者Andrew Judd
相关产品推荐
相关产品推荐

