如何使用游标比较两个不同表的两列中的值

时间:2015-01-01 07:42:50

标签: sql oracle oracle11g cursor

declare
    v_column varchar2(100);
    v_incident_id number;
    v_check_incident  varchar2(100);
    v_check_audit varchar2(100);
    query_str varchar2(1000);
    cursor c1 is
        select COLUMN_NAME 
        from ALL_TAB_COLUMNS 
        where upper(TABLE_NAME)=upper('Incidents');
begin
    open c1;
    loop
        fetch c1 into v_column;
        exit when c1%notfound;
        select incident_id into v_incident_id from incident_audit;
        DBMS_OUTPUT.PUT_LINE('incident column: '||v_column);
        select v_column 
        into v_check_incident 
        from incidents 
        where incident_id= v_incident_id;   
        select  to_char(v_column) 
        into v_check_audit  
        from incident_audit  
        where incident_id=v_incident_id; 
        DBMS_OUTPUT.PUT_LINE('incident column: '||v_check_incident);
        DBMS_OUTPUT.PUT_LINE('audit column : '||v_check_audit);
        if(v_check_incident != v_check_audit)
        then
            DBMS_OUTPUT.PUT_LINE('inside insert');
            insert into PHIIT_AUD(AUDIT_ID ,INCIDENT_ID,OLD_VALUE,NEW_VALUE,UPDATED_BY,UPDATED_ON,COLUMN_NAME)
            values(audit_id_seq.nextval,v_incident_id,v_check_audit,v_check_incident,NVL(v('APP_USER'),USER),sysdate,v_column);
        end if;
    end loop;
    DBMS_OUTPUT.PUT_LINE('Total number of rows : '||c1%ROWCOUNT);
    close c1;
end;

问题:从游标中的ALL_TAB_COLUMNS获取列名,并使用它与其他表的其他列进行比较

output : incident column: INCIDENT_ID
incident column: INCIDENT_ID
audit column : INCIDENT_ID
incident column: BUSINESS_UNIT_ID
incident column: BUSINESS_UNIT_ID
audit column : BUSINESS_UNIT_ID

光标返回值为column_name而不是其值,以便进行比较。

1 个答案:

答案 0 :(得分:2)

  

"光标返回值为column_name"

当然,这就是你要告诉它的事情。 select v_column from incidents表示选择变量中的值。

您需要做的是使用动态SQL 创建一个select语句,用于将变量中的值替换为列名:'select '||v_column||' from incidents'

这是你需要做的事情。

declare
    v_column varchar2(100);
    v_incident_id number;
    v_check_incident  varchar2(100);
    v_check_audit varchar2(100);
    query_str varchar2(1000);
    cursor c1 is
        select COLUMN_NAME 
        from ALL_TAB_COLUMNS 
        where upper(TABLE_NAME)=upper('Incidents');
    rc sys_refcursor;
begin
    open c1;
    loop
        fetch c1 into v_column;
        exit when c1%notfound;
        select incident_id into v_incident_id from incident_audit;
        DBMS_OUTPUT.PUT_LINE('incident column: '||v_column);
        --  dynamic SQL
        open rc for 
            'select'|| v_column ||
             ' from incidents where incident_id= :1'
             using v_incident_id;   
        fetch rc into v_check_incident;
        close rc;
        open rc for 
            'select'|| v_column ||
             ' from incident_audit   where incident_id= :1'
             using v_incident_id;   
        fetch rc into v_check_audit;
        close rc;
        DBMS_OUTPUT.PUT_LINE('incident column: '||v_check_incident);
        DBMS_OUTPUT.PUT_LINE('audit column : '||v_check_audit);
        if(v_check_incident != v_check_audit)
        then
            DBMS_OUTPUT.PUT_LINE('inside insert');
            insert into PHIIT_AUD(AUDIT_ID ,INCIDENT_ID,OLD_VALUE,NEW_VALUE,UPDATED_BY,UPDATED_ON,COLUMN_NAME)
            values(audit_id_seq.nextval,v_incident_id,v_check_audit,v_check_incident,NVL(v('APP_USER'),USER),sysdate,v_column);
        end if;
    end loop;
    DBMS_OUTPUT.PUT_LINE('Total number of rows : '||c1%ROWCOUNT);
    close c1;
end;

我保持它接近你原来的实现,所以你可以理解这个原理。但是,我认为这是一个糟糕的实现,如果您需要进行大量的审核来验证,这将是非常低效的。但解决这个问题是另一回事。