2012-09-06 38 views
1

我想結合幾個查詢中的一些字段具有不同的數據類型的記錄。這些不同的查詢不僅用於選擇所需的記錄,而且還用於確保每個查詢具有完全相同順序的完全相同的字段名稱。每個查詢都會返回10個或更少的記錄。另外,這些查詢中的一個或多個查詢可能根本不會返回任何記錄。如何組合混合數據類型? Varray和Varchar2是正確的選擇嗎?

難點在於數據類型在這些不同的數據源中是不同的。例如,名爲fld_Shirt_Size的列可能具有數字值,例如來自一個數據源的(15.5, 17, 20),但該字段的另一個數據源的文本值爲('Small', 'Medium', 'Large')。這兩個數據源都可以包含與其他值混合的空值。

我試圖使用聯合或聯合所有方法來加入這些查詢和不同的數據類型,使其無法正常工作。然後,我嘗試使用VARCHAR2作爲數據類型創建VARRAY,然後使用每個查詢中的記錄填充該數組,但是又收到有關數據類型的錯誤。

我需要將數字和文本保留爲文本,所以使用轉換方法將每個值設置爲文本字符串不是一個選項。上面的簡單例子是爲了說明我正在使用的情況,但真實數據是財務和稅務數據,其中一些字段在一些年份中不存在,並且需要文本值來記錄(例如‘N/A’‘Did Not Exist’),而其他字段有NULL值與零貨幣值不同,這就是爲什麼數字需要保留數字,並且文本需要保留文本,即使它們全都在同一個字段中。這些結果將被顯示,並且稍後將在Excel中使用。每個查詢都被用來「修飾」底層數據,以確保所有這些查詢都具有相同的字段名稱。

我在一個只讀環境中使用PL/SQL Oracle 9i(沒有創建表權限等),同時我對sql也很新,但是擁有多年的MS Access經驗。沒有與此數據的ODBC連接可用。

我的測試代碼(下面附帶)產生以下錯誤消息:然後

ORA-06550: line 87, column 54: 
PLS-00382: expression is of the wrong type 
ORA-06550: line 87, column 9: 
PL/SQL: Statement ignored 
ORA-06550: line 90, column 54: 
PLS-00201: identifier ‘D_INTERANL_ID’ must be declared 
ORA-06550: line 90, column 9: 
PL/SQL: Statement ignored… 

該錯誤消息重複用於每個其它類似的線。

此測試版代碼僅包含每個查詢的標準佈局的幾個字段,目前僅用於查找可行的方法。真正的標準佈局查詢每個都有大約350個字段,這些查詢中有15個需要將他們的結果與每年添加的其他查詢結果組合在一起。

任何幫助,非常感謝。我一直在搜索這個站點和其他站點,試圖找到正確的代碼並使語法起作用。

DECLARE 
    MyTID varchar2(10); 
    MyRecordCountOfVarray number; 
    MyCursorRowCounter number; 
    MyRowPositionInVarray number; 
CURSOR Cursor_rst1 IS 
     SELECT d_owner_internal_id, 
       d_internal_id, 
       d_tid, 
       d_entity_name, 
       d_form_seq 
     FROM rtns.itas_rtn_ct_1120_cor tblRecords 
     WHERE d_form_seq = '2710' --Tax Year =2003 
      AND D_TID = MyTID; 
CURSOR Cursor_rst2 IS 
     SELECT d_owner_internal_id, 
       d_internal_id, 
       d_tid, 
       d_entity_name, 
       d_form_seq 
     FROM rtns.itas_rtn_ct_1120_cor tblRecords 
     WHERE d_form_seq = '11625' --Tax Year =2004 
      AND D_TID = MyTID; 
TYPE MyVarray IS VARRAY(500) OF VARCHAR2(100); 
    v_owner_internal_id    MyVarray :=MyVarray(); 
    v_internal_id     MyVarray :=MyVarray(); 
    v_tid       MyVarray :=MyVarray(); 
    v_entity_name     MyVarray :=MyVarray(); 
    v_form_seq      MyVarray :=MyVarray(); 
BEGIN 
    MyTID := '0000083'; 
MyRecordCountOfVarray:=v_owner_internal_id.COUNT; 
FOR d_owner_internal_id IN Cursor_rst1 
    LOOP 
     MyCursorRowCounter :=Cursor_rst1%ROWCOUNT; 

     MyRowPositionInVarray := MyRecordCountOfVarray + MyCursorRowCounter; 

v_owner_internal_id.extend; 
    --************************************** 
    --* First ERROR shows up on next line 
    --ORA-06550: line 87, column 54: 
    --PLS-00382: expression is of the wrong type 
    --ORA-06550: line 87, column 9: 
    --PL/SQL: Statement ignored 
    --**************************************   
    v_owner_internal_id(MyRowPositionInVarray) :=d_owner_internal_id;  
 v_internal_id.extend; 
    --**************************************** 
    --* Second ERROR shows up on next line 
    --ORA-06550: line 90, column 54: 
    --PLS-00201: identifier ‘D_INTERANL_ID’ must be declared 
    --ORA-06550: line 90, column 9: 
    --PL/SQL: Statement ignored… 
    --****************************************   
    v_internal_id(MyRowPositionInVarray)  :=d_internal_id; 
 v_tid.extend; 
     v_tid(MyRowPositionInVarray)    :=d_tid; 

     v_entity_name.extend; 
     v_entity_name(MyRowPositionInVarray)  :=d_entity_name; 

     v_form_seq.extend; 
     v_form_seq(MyRowPositionInVarray)   :=d_FORM_SEQ;   


    END LOOP; 
-- Review output 
    FOR i IN v_owner_internal_id.first .. v_owner_internal_id.last 
    LOOP dbms_output.put_line(v_owner_internal_id(i) || ', ' || 
          v_internal_id(i) || ', ' || 
          v_tid(i) || ', ' || 
          v_entity_name(i) || ', ' || 
          v_form_seq(i)); 
    END LOOP; 
END; 

回答

1

你的問題是遊標循環中的變量總是基於遊標定義的tabletype。您需要指定要添加到陣列中的字段從表:

v_owner_internal_id(MyRowPositionInVarray) := d_owner_internal_id.d_owner_internal_id; 

同樣,你的任務的其餘部分將需要隨之改變:

v_internal_id(MyRowPositionInVarray) := d_owner_internal_id.d_internal_id; 

顯然,它會將光標循環使用的變量更改爲不太令人困惑的東西是一個好主意。


您還可以使用光標來定義數組簡化這一點:

TYPE t_rst1 IS VARRAY(500) OF cur_rst1%rowtype; 
v_rst1 t_rst1 := t_rst1(); 
... 
for r_rst1 in cur_rst1 loop 
... 
v_rst1(MyRowPositionInVarray) := r_rst1; 
... 
dbms_output.put_line(v_rst1(i).d_owner_internal_id || ', ' || 
        v_rst1(i).d_internal_id || ', ' || 
        v_rst1(i).d_tid || ', ' || 
        v_rst1(i).d_entity_name || ', ' || 
        v_rst1(i).d_form_seq); 

最後,可以大大利用bulk collect簡化這個:

DECLARE 
    MyTID varchar2(10); 
CURSOR Cursor_rst1 IS 
     SELECT d_owner_internal_id, 
       d_internal_id, 
       d_tid, 
       d_entity_name, 
       d_form_seq 
     FROM rtns.itas_rtn_ct_1120_cor tblRecords 
     WHERE d_form_seq = '2710' --Tax Year =2003 
      AND D_TID = MyTID; 
    TYPE t_rst1 IS table OF Cursor_rst1%rowtype; 
    r_rst1 t_rst1; 

    BEGIN 
    MyTID := '0000083'; 

    open Cursor_rst1; 
    fetch Cursor_rst1 bulk collect into r_rst1; 
    close Cursor_rst1; 

    FOR i IN r_rst1.first .. r_rst1.last LOOP 
     dbms_output.put_line(r_rst1(i).d_owner_internal_id || ', ' || 
          r_rst1(i).d_internal_id || ', ' || 
          r_rst1(i).d_tid || ', ' || 
          r_rst1(i).d_entity_name || ', ' || 
          r_rst1(i).d_form_seq); 
    END LOOP; 
END; 
+0

感謝您的幫助。我收到一個錯誤。 ORA-06550:第17行,第10欄:PLS-00201:必須聲明標識符'r_rst1'。另外,我能做些什麼,BULK COLLECT追加到數組的底部,並且不會覆蓋從第一行開始的任何先前值? – user1652509

+0

我找到並添加了一行:'r_rst1 t_rst1;',並擺脫了錯誤信息。非常感謝你的幫助。我仍然希望在數組末尾添加多個'BULK COLLECT'。任何想法如何做到這一點? – user1652509

+0

@ user1652509 - 'bulk collect'不能用於將記錄追加到數組中。但是,您可以通過使用「UNION ALL」組合兩個查詢來獲得相同的結果。 – Allan