2017-07-11 160 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个联合生成一个庞大的查询,它会生成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!它看起来更有效率。我得到的唯一的错误是“从关键字找不到....在44行”....我检查看看我需要做的代码..再次感谢! – LycorisRadiata