2009-11-04 96 views
0

我正在寫一個存儲過程,我需要根據所報告的數據填充表。Oracle動態SQL列

在這種情況下,我會在日期範圍內爲特定代碼每天提取三個值。

看這個存儲過程的某個來看,我有代碼值X,Y和Z的日期範圍爲這樣:

select abc.code, 
     abc.date, 
     abc.val_1, 
     abc.val_2, 
     abc.val_3 
    from data.abc 
where abc.date BETWEEN '01-OCT-2009' AND '31-OCT-2009' 

因此,對於每一天的日期範圍,我有三個代碼x,y和z的記錄。

在我的最終表格中,我需要將它從行轉換爲列。通常我會使用解碼函數,但在這裏我想根據返回的數據動態創建我的最終表。

在這種情況下,我會在範圍內每天有一條記錄,並有9列(val_1_X,val_2_x,val_3_x,val_1_y等等)。

我想動態設置它,以便在引入新「代碼」時不需要重新打開存儲過程,因此在報告的每個實例上只返回「代碼」在那個報告的例子中包含在決賽桌上。

這是可能的通過動態sql?我在Oracle版本10g上。

+0

我建議讓報告工具做任何交叉表/多維數據集/數據透視表,只是擔心查詢返回正確的數據來支持它。 – Brian 2013-03-06 09:37:42

回答

1

從我的理解,01-OCT-2009 31-OCT-2009只有代碼Xÿž,而經歷到1​​1月30日,2009年還可能會產生你瓦特

最後,你想這樣的查詢:

CREATE TABLE t1 AS 
    SELECT 
    abc.date, 
    MAX(DECODE(code, 'x', val_1, NULL)) AS abc_val_1_x, 
    MAX(DECODE(code, 'x', val_2, NULL)) AS abc_val_2_x, 
    MAX(DECODE(code, 'x', val_3, NULL)) AS abc_val_3_x, 
    MAX(DECODE(code, 'y', val_1, NULL)) AS abc_val_1_y, 
    MAX(DECODE(code, 'y', val_2, NULL)) AS abc_val_2_y, 
    MAX(DECODE(code, 'y', val_3, NULL)) AS abc_val_3_y, 
    ... 
    FROM data.abc 
    WHERE abc.date BETWEEN '01-OCT-2009' AND '31-OCT-2009' 
    GROUP BY abc.date 

我不是一個Oracle傢伙,沒有獲得測試甲骨文,所以你可能會發現不少的語法錯誤之類下面。您還需要將硬編碼的日期更改爲變量,聲明一些變量並實際運行創建的查詢。

-- Figure out all valid codes for date range. 
-- Might also require ordering depending on your report. 
CURSOR c1 
    IS 
    SELECT 
     abc.code 
    FROM data.abc 
    WHERE abc.date BETWEEN '01-OCT-2009' AND '31-OCT-2009' 
    GROUP BY abc.code; 

query1 := 'CREATE TABLE abc_report AS SELECT date'; 
LOOP 
    FETCH c1 INTO code1 
    EXIT WHEN c1%NOTFOUND; 
    query1 := query1 || ', DECODE(code, ''' || code1 || ''', val_1, NULL)) AS abc_val_1_' || code1 || 
     ', DECODE(code, ''' || code1 || ''', val_2, NULL)) AS abc_val_2_' || code1 || 
     ', DECODE(code, ''' || code1 || ''', val_3, NULL)) AS abc_val_3_' || code1 
END LOOP; 
query1 := query1 || ' FROM data.abc WHERE date BETWEEN ''01-OCT-2009'' AND ''31-OCT-2009''' 
0

非常感謝您的幫助,但事實證明,我終究無法走上這條道路。所存儲的程序將被啓動並由報告工具使用,並且我需要爲可能會同時運行此報告的多個實例做準備,所以我不能重新使用表名,可以允許存儲過程創建對每個運行實例唯一的表。

感謝您的幫助,但!

+1

嗨!歡迎來到StackOverflow! 這是一個迴應lins314159的回答? StackOverflow僅在其答案上通知*評論*的用戶。除非他再次訪問這個問題,否則他不會知道你是否做出這個決定。 以及lins314159的答案是否真的解決了*原始問題?如果是這樣,你可以考慮接受他的回答以換取他的努力。 以後! :) – 2009-11-04 15:48:58

0

對於多個實例,使用具有提交刪除行選項的全局臨時表或基於需求提交保留。無論選項如何,記錄將僅適用於該會話。