我有一个包含30多个字段的表,我想获取不同的字段名称和值。
例如在表X中,我们有
ID | City | State | Zip | Segment_One | Segment_Two | .... 1 | | NY | 14228 | X71 | 5 | 2 | JamesTown | NY | 14845 | X72 | 5 |
查询应返回字段名称和数据的差异。
ID | City | Zip | Segment_One 1 | | 14228 | X71 2 | JamesTown | 14845 | X72
我可以使用一个查询来始终将行限制为两行。…所以我想我总是会在两行之间进行比较,但是如何找到字段名称的不同并获取这些字段的值呢?
编辑:这是我尝试过的方法,但即使它与众不同,它似乎也会返回状态。
select * from (select a.* from X a where ROWNUM = 1 order by last_updt_date desc ) minus select * from (select b.* from X b where ROWNUM = 2 order by last_updt_date desc );
结果:
ID | City | State | Zip | Segment_One | Segment_Two | 1 | | NY | 14228 | X71 | 5 | ...
这将返回该行中的所有字段,但我只需要差异字段和值。这不会在第2行返回。如果我将减号取反,它将什么也不会返回。
您可以使用PL / SQL块和Dynamic尝试这样的操作CURSOR。请注意,这里我使用ID = 1和2作为变量,您应该知道该变量并将其从某个地方传递。
CURSOR
DBMS_SQL.RETURN_RESULT(12c及更高版本)用于显示动态构造的游标的输出。或者,您可以使用PRINTcommand从中获取并显示o / p REFCURSOR。
DBMS_SQL.RETURN_RESULT
PRINT
REFCURSOR
SET serveroutput ON DECLARE v_ref SYS_REFCURSOR; id1 X.ID%TYPE := 1; id2 X.ID%TYPE := 2; v_col VARCHAR2(32); v_cols VARCHAR2(1000); BEGIN FOR r IN ( SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = 'X' ) LOOP EXECUTE IMMEDIATE ' SELECT CASE WHEN a.'||r.column_name|| ' = ' || 'b.'|| r.column_name ||' THEN a.'||r.column_name || ' END FROM X a CROSS JOIN X b WHERE a.ID = :Id1 AND b.ID = :Id2' INTO v_col USING id1,id2 ; v_cols := v_cols || CASE WHEN v_col IS NULL THEN ','||r.column_name END; END LOOP; v_cols := TRIM(BOTH ',' FROM v_cols); OPEN v_ref FOR 'select ' || v_cols || ' FROM X WHERE ID = '||id1||' UNION ALL select ' || v_cols || ' FROM X WHERE ID = '||id2 ; DBMS_SQL.RETURN_RESULT(v_ref); END; /
ResultSet #1 ID CITY ZIP SEGMENT_ONE ------------------ --------- ------------ ----------- 1 14228 X71 2 JamesTown 14845 X72 PL/SQL procedure successfully completed.