查询以查找列中的delta

时间:2014-03-26 18:32:24

标签: oracle oracle11g

我想写一个查询,它将从两个表1中读取相同的列。来自主表2.来自审计表。如果值有变化,则返回列名以及它的新旧值。

主查询:select issue_date,issue_price,issue_entity from voucher where voucher_id=x;
审核查询:select issue_date,issue_price,issue_entity from voucher_audit where version=2 and voucher_id=x;

请注意,凭证和voucher_audit具有相同的表结构,但审计表中的版本号是额外的。

那么结果应该是

column_name  old_value new_value
issue_price  36        38 
issue_date   01/03/14  02/03/14 

1 个答案:

答案 0 :(得分:0)

您应该获取两个表中具有相同名称的所有列。然后,您应该使用动态SQL获取每列的值。

DECLARE
  input_voucher_id VARCHAR2(100) := '&voucher_id';
  input_version VARCHAR2(100):='&version';
  CURSOR c_common_column IS
    SELECT u.COLUMN_NAME
    FROM   user_tab_cols u
    WHERE  u.TABLE_NAME = 'VOUCHER'
           AND EXISTS
     (SELECT 1
            FROM   user_tab_cols u1
            WHERE  u1.TABLE_NAME = 'VOUCHER_AUDIT'
                   AND u1.COLUMN_NAME = u.COLUMN_NAME);
  v_first_sql        VARCHAR2(1000):='' ;
  v_second_sql       VARCHAR2(1000) :=''; 
  first_table_value  VARCHAR2(100) := '';
  second_table_value VARCHAR2(100) := '';
BEGIN
  dbms_output.put_line('Column Name,old_value,new_value');
  FOR x IN c_common_column   LOOP
    v_first_sql:='SELECT '||x.COLUMN_NAME|| ' from voucher where voucher_id=:voucher_id';
    v_second_sql :='SELECT '||x.COLUMN_NAME|| ' from voucher_audit where voucher_id=:voucher_id and version = :version';
    EXECUTE IMMEDIATE v_first_sql
      INTO first_table_value
      USING  input_voucher_id;
    EXECUTE IMMEDIATE v_second_sql
      INTO second_table_value
      USING  input_voucher_id, input_version;
    if first_table_value != second_table_value then 
        dbms_output.put_line(x.COLUMN_NAME ||','|| first_table_value || ',' ||
                         second_table_value);
    end if;
  END LOOP;
END;