2016-03-01 69 views
0

我必須每天加載一些文件到我們的數據庫系統。我的解決方案是使用java過程來生成目錄文件夾中所有文件的表格,並通過外部表格加載程序遍歷每個文件。我正在爲兩個掛斷本掛在For For循環和外部表加載器的變量

Declare 
what_to_load  VARCHAR2(255); 

CURSOR folder_contents 
IS 
    select filename 
    from database.DIR_LIST 
    where filename like 'DCOpenOrders_%' 
    and filename like '%.csv'; 

BEGIN 
    DELETE FROM database.DIR_LIST; 
    database.GET_DIR_LIST('directory_path_files_are_in'); 
FOR each_record IN folder_contents 
    LOOP 

what_to_load := each_record.filename; 

EXECUTE IMMEDIATE 'DROP table database.my_table'; 

execute immediate 'CREATE table database.my_table 
     (Region     VARCHAR2(10), 
     District    VARCHAR2(10), 
     Originating_Store  VARCHAR2(80), 
     Order_Date    VARCHAR2(30), 
     Ship_Location   VARCHAR2(10), 
     Orig_Ord_No   VARCHAR2(30), 
     Field_G    VARCHAR2(30), 
     Line_No    VARCHAR2(10), 
     POS_UPC    VARCHAR2(30), 
     Item_Descr    VARCHAR2(80), 
     Ord_Qty    VARCHAR2(10), 
     Line_Status   VARCHAR2(30), 
     Report_Date   VARCHAR2(30), 
     Ship_Type    VARCHAR2(30), 
     ERR_FLAG    VARCHAR2(10), 
     ERR_LOG    VARCHAR2(800) 
     ) 
     ORGANIZATION EXTERNAL 
      (type oracle_loader 
      default directory WORK_DIR 
      access parameters 
      (records delimited by NEWLINE 
       skip 1 
       fields terminated by '','' 
       optionally enclosed by ''"'' 
       missing FIELD VALUES are NULL) 
       location ('''||each_record.filename||''') 
      ) 
       reject limit unlimited'; 

Execute Immediate 'Grant All on database.my_table to USER'; 
* merge statement goes here* 
End Loop; 
commit; 
end; 

同樣,這個想法是,每到這個運行時,它會得到的CSV文件中新的列表中dir_list表與Java程序get_dir_list,然後對每個文件名時我設置爲等於變量,並使用外部表加載器中的變量來加載文件。

我運行到[S] 2個[/ s]的問題

編輯:好吧,讓下面光標的行標識的修正,現在我打哪裏,當我去第二次通過點我光標看起來是錯的或丟失了 - 如果唯一的動作是做put_line,它會經過一個循環。但是在那裏執行立即聲明,例如「全部授予」,那麼只要它完成一次傳遞,它就會在循環的頂部拋出ORA-08103並拒絕繼續。

3)我知道在這個問題上(https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:37593123416931),說要使用alter table命令。然而,當我嘗試它不接受我的那個

execute immediate 'alter table database.my_table location('''||filename||''')'; 

嘗試拋出了一個錯誤(加上我仍然需要得到它做另一個循環有沒有把這個名字當前文件的進外部裝載機)

任何建議或幫助?我應該注意到,我們在windows而不是unix(因爲人們在這些地方提供的大多數解決方案都假設爲後者),並且由於批准限制(因爲這似乎是另一個常見問題),所以我不能抓住另一個程序或模塊來完成這項工作解決方案)

謝謝!

+2

那麼,錯誤是什麼? – OldProgrammer

+0

對於第一點,錯誤是PLS-00382:表達式類型錯誤。對於第2點沒有錯誤消息,它只是掛起執行,直到你終止進程 – user6004930

+0

而對於第3點,改變「拋出一個錯誤」?我猜這也是PLS-00382出於同樣的原因。 –

回答

1

對於第一個問題,您的光標循環變量被混淆地稱爲filename。你指的是直接記錄,而不是光標所在的列。稍微改變了名稱,以使其更清晰一點:

FOR filenames IN folder_contents 
    LOOP 

what_to_load := filesnames.filename; 

其餘的是不太明顯,但它不會是快樂的,你刪除和塊中的指向中間重新創建表靜態地。您需要使所有參考動態:

execute immediate 'Grant All on database.my_table ...'; 
-- grant to who/what? and why? 

而且你的合併也必須是動態的。至少除非你能讓alter table起作用,但你還沒有說過這個問題是什麼。其實,從你貼什麼,這是相同的遊標變量引用的問題:

execute immediate 'alter table database.my_table location('''||filenames.filename||''')'; 

如果你不會放棄/塊中創建表,一旦靜態創建它,只是改變它,那麼你可以使用一個靜態的合併 - 只需要改變動態。


一個更簡單的方法可能是創建一次外部表,具有特定的固定名稱;循環遍歷真實文件的列表;然後爲每個人重新命名或將其複製到固定文件名並執行合併。每次查詢外部表時,它都會重新讀取該文件,因此在後臺更改其內容是可以的。丟棄/重新創建或甚至改變表格將不是必需的。

如同Ask Tom pst提到的那樣,您可以同時將所有文件名提供給外部表,因爲它們具有相同的結構,可以使用drop/create或alter方法。

+0

這個(在光標上的記錄中更具體)幫助了變量鏈接,但它在第一遍完成循環並且返回到開始時仍然被掛起。 該贈款是因爲合併以及稍後在此過程中需要執行的一些其他操作,因此我將其授予特定個人資料,但由於公司隱私問題,不希望在網上發帖。 – user6004930

+0

無論如何,我認爲授權必須在你的真實代碼中是動態的。合併?你如何檢查它是否合併並返回到循環的開始? –

+0

不,我把這筆資金作爲一般資料給它,沒有變量,它只是指我剛創建的表。 合併是從臨時表到臨時表,在那裏沒有任何動態。現在我沒有測試那部分;我把它評論了出來。目前我只看到我是否可以通過列表來加載所有內容。 – user6004930