2017-07-11 1 views
0

私は動的カーソルに変えたいという基本的なSQLクエリを持っています。Oracle - 列のリストをループする

私は、私は値が前回の実行以降に変更されたかどうかをチェックしています列のリストを持って、私はチェックしています列が含まれます:などの収入、人種、

前アンドの出力を値の変更元などの追加の調査のために、一時的または永続的なテーブルに値を格納する必要がある...

600+以上のリストがあるので、私は望んでいないと思うベースSQLを600回コンパイルするには

このタスクを実行するための動的SQLカーソルの書き方はありますか?
ありがとうございます!

---ベースのSQL

SELECT a.*, 
     'Last_name' AS "field_name", 
     b.LAST_name AS last_name_updated 
from 
    (SELECT person_id, last_name 
    FROM person 
    WHERE batch_id = (select max(batch_id) from person) 
    ) a 
FULL OUTER JOIN 
    (SELECT person_id, last_name 
    FROM person 
    WHERE batch_id = (select max(batch_id) - 1 from person) 
    ) b 
ON a.person_id = b.person_id 
WHERE nvl(a.last_name,0) <> nvl(b.last_nm,0) 

UNION 

SELECT a.*, 
     'Income', 
     b.income AS income_updated 
from 
    (SELECT person_id, income 
    FROM person 
    WHERE batch_id = (select max(batch_id) from person) 
    ) a 
FULL OUTER JOIN 
    (SELECT person_id, income 
    FROM person 
    WHERE batch_id = (select max(batch_id) - 1 from person) 
    ) b 
ON a.person_id = b.person_id 
WHERE nvl(a.income,0) <> nvl(b.income,0) 

---所望の出力

person_id || field_name || previous_value || updated_value 
8783  || income  || 95000   || 98000 
235731  || last_name || Dawson   || Dawson Jr. 

答えて

0
ここ

あなたが始めるために何かです。 600ユニオンで1つの膨大なクエリを生成するのではなく、600のクエリを生成し、順次実行します。各繰り返しの結果を別の表に保存するコードを追加する必要があります。

declare 
    l_sql long; 
    l_default varchar2(10); 
    l_max_batch_id number; 
    rc sys_refcursor; 
begin 
    select max(batch_id) 
    into l_max_batch_id 
    from person; 

    for r in (select column_name, data_type 
       from user_tab_columns 
      where table_name = 'PERSON' 
       and column_name not in ('PERSON_ID') -- Exclude any other columns you don't want to compare 
      ) 
    loop 
    l_sql := q'[SELECT a.person_id, 
         a.col  AS new_value 
         '#COL#' AS column_name, 
         b.#COL# AS old_value 
        from 
         (SELECT person_id, #COL# 
         FROM person 
         WHERE batch_id = #MAXBATCH# 
        ) a 
        FULL OUTER JOIN 
         (SELECT person_id, #COL# 
         FROM person 
         WHERE batch_id = #MAXBATCH#-1 
        ) b 
        ON a.person_id = b.person_id 
        WHERE nvl(a.#COL#,#DEFAULT#) <> nvl(b.#COL#,#DEFAULT#)]'; 

    l_sql := replace (l_sql, '#COL#', r.column_name);     
    l_sql := replace (l_sql, '#MAXBATCH#', l_max_batch_id);     

    l_default := case r.data_type 
        when 'NUMBER' then '0' 
        when 'DATE' then q'[DATE '4000-31-12']' 
        else q'['~~~']' 
        end; 

    l_sql := replace (l_sql, '#DEFAULT#', l_default); 
    open rc for l_sql; 
    -- Now fetch all the data and e.g. write to a table... 
    end loop; 
end; 
+0

Thanks @Tony Andrews!より効率的に見えます。私が得ている唯一のエラーは、 "FROMキーワードが見つからない.... 44行目"です....私はコードで何をする必要があるかを確認しています。もう一度ありがとう! – LycorisRadiata

関連する問題