嵌套表含多列时如何使用MEMBER OF函数匹配列值并返回对应数据?
双列嵌套表匹配Column2获取对应Column1的问题
我之前在单列嵌套表中用MEMBER OF函数一直没问题,但现在碰到含两列(Column1、Column2)的嵌套表TABLEA,想匹配Column2的值后返回对应的Column1,写的代码却报错,求帮忙解决。
嵌套表数据:
| Column1 | Column2 |
|---|---|
| 1 | AA |
| 2 | BB |
| 3 | CC |
| 4 | DD |
报错代码:
IF 'AA' MEMBER OF TABLEA.COLUMN2 THEN DBMS_OUTPUT.PUT_LINE(TABLEA.COLUMN1); ELSE DBMS_OUTPUT.PUT_LINE('NOT Found.'); END IF;
问题原因
MEMBER OF只能用于单列集合(比如单列嵌套表、数组),你的TABLEA是包含两个字段的对象类型集合,没法直接通过TABLEA.COLUMN2提取出单列集合,这是语法报错的根本原因。- 退一步说,就算语法没问题,
TABLEA.COLUMN1也没法直接返回匹配行的对应值——因为TABLEA是一整组记录的集合,不是单条数据。
解决方法
方法1:循环遍历嵌套表找匹配项
直接遍历集合里的每个元素,判断Column2是否符合条件,找到就输出对应Column1:
DECLARE -- 先定义对象类型和嵌套表类型(如果你的代码里已经定义过,可以跳过这部分) TYPE table_obj IS OBJECT ( Column1 NUMBER, Column2 VARCHAR2(10) ); TYPE tablea_type IS TABLE OF table_obj; TABLEA tablea_type := tablea_type( table_obj(1, 'AA'), table_obj(2, 'BB'), table_obj(3, 'CC'), table_obj(4, 'DD') ); v_found BOOLEAN := FALSE; BEGIN FOR i IN TABLEA.FIRST .. TABLEA.LAST LOOP IF TABLEA(i).Column2 = 'AA' THEN DBMS_OUTPUT.PUT_LINE(TABLEA(i).Column1); v_found := TRUE; EXIT; -- 找到就停,不用继续遍历 END IF; END LOOP; IF NOT v_found THEN DBMS_OUTPUT.PUT_LINE('NOT Found.'); END IF; END; /
方法2:用SQL查询(结合TABLE()函数)
把嵌套表转成关系表,用SQL直接查匹配的Column1:
DECLARE TYPE table_obj IS OBJECT ( Column1 NUMBER, Column2 VARCHAR2(10) ); TYPE tablea_type IS TABLE OF table_obj; TABLEA tablea_type := tablea_type( table_obj(1, 'AA'), table_obj(2, 'BB'), table_obj(3, 'CC'), table_obj(4, 'DD') ); v_column1 NUMBER; BEGIN SELECT Column1 INTO v_column1 FROM TABLE(TABLEA) WHERE Column2 = 'AA'; DBMS_OUTPUT.PUT_LINE(v_column1); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('NOT Found.'); END; /
方法3:用集合FILTER方法(Oracle 12c+可用)
如果你的Oracle版本是12c或更高,能直接用集合的FILTER方法筛选匹配项:
DECLARE TYPE table_obj IS OBJECT ( Column1 NUMBER, Column2 VARCHAR2(10) ); TYPE tablea_type IS TABLE OF table_obj; TABLEA tablea_type := tablea_type( table_obj(1, 'AA'), table_obj(2, 'BB'), table_obj(3, 'CC'), table_obj(4, 'DD') ); v_filtered tablea_type; BEGIN v_filtered := TABLEA.FILTER( FUNCTION(obj table_obj) RETURN BOOLEAN IS BEGIN RETURN obj.Column2 = 'AA'; END ); IF v_filtered.COUNT > 0 THEN DBMS_OUTPUT.PUT_LINE(v_filtered(1).Column1); ELSE DBMS_OUTPUT.PUT_LINE('NOT Found.'); END IF; END; /
内容的提问来源于stack exchange,提问作者Venkatesh R
相关产品推荐
相关产品推荐

