2016-09-27 26 views
0

我必須從結構這樣的文件中插入多個行插入表中插入多行:如何從流動

BANAC2C100017701007_X75 _CA  4X2 CT  MLCR DR  SX  EP  160 E4 

,其中4×2,mlcR的,160 E4必須插入到同一列相同的代碼BANAC2C100017701007。作爲例子,該表必須是這樣的:

enter image description here

後分裂從文件中的元素,我怎樣才能把它們放進表?任何建議?

+0

你可以使用sqlldr嗎?數據是否有分隔符?還是固定長度的字段?或者他們至少有相同數量的元素一行? –

回答

0

它可以用sqlldr完成。我做了一些假設,但是如果數據是上面描述的每行一行,並且具有相同數量的元素一行,則具有多個「到表」語句的正確構建的控制文件可以寫入一行數據的不同部分作爲多行到同一個表。

控制文件:

LOAD DATA 
infile "file.dat" 
TRUNCATE 
INTO TABLE data_table 
(entirerow BOUNDFILLER char(4000) 
,code expression "regexp_substr(:entirerow, '(.*?)(_)', 1, 1, NULL, 1)" 
,desc expression "regexp_substr(:entirerow, '(.*?)(+)', 1, 3, NULL, 1)" 
) 
INTO TABLE data_table 
(entirerow BOUNDFILLER position(1) char(4000) 
,code expression "regexp_substr(:entirerow, '(.*?)(_)', 1, 1, NULL, 1)" 
,desc expression "regexp_substr(:entirerow, '(.*?)(+)', 1, 5, NULL, 1)" 
) 
INTO TABLE data_table 
(entirerow BOUNDFILLER position(1) char(4000) 
,code expression "regexp_substr(:entirerow, '(.*?)(_)', 1, 1, NULL, 1)" 
,desc expression "regexp_substr(:entirerow, '(.*?)(+)', 1, 9, NULL, 1) || ' ' || 
        regexp_substr(:entirerow, '(.*?)(+|$)', 1, 10, NULL, 1)" 
) 

幾件事情需要注意:

因爲沒有分隔符,沒有被指定,整個行將被讀入第一場「entirerow」 。由於它不是表格中的一列,它被定義爲BOUNDFILLER,它被「記住」以備後用。

在控制文件中找到下一個字段「代碼」。不存在與其匹配的數據字段,但sqlldr發現它與表中的列匹配,並且看到它是表達式,因此它將表達式應用於將結果放入列中。該表達式使用REGEXP_SUBSTR對記憶的BOUNDFILLER剪切我們需要的部分。對於代碼,請獲取字符,但不包括第一個下劃線。對於desc,獲取第三組字符,其後跟一個或多個空格(但不包括空格)。

對於第二個邏輯行,我們需要將邏輯指針重新定位回讀入的行的開始位置,以便sqlldr可以重新處理。否則,邏輯指針位於數據的末尾,不會返回任何內容。這是通過第二個和第三個「into table」語句的「wholerow」定義中的「position」參數完成的。最後的「進入桌子」遵循先前的第9和第10場並將它們連接在一起的範例。我選擇這樣做,而不是拿出另一個正則表達式來實現它,因爲它與其他領域保持一致,再加上如果你想在將來改變它,它會更容易遵循。

正如你可以看到它的工作原理是可重複使用的:

SQL> select code, desc 
    from data_table; 

CODE      DESC 
------------------------- ------------- 
BANAC2C100017701007  4X2 
BANAC2C100017701007  MLCR 
BANAC2C100017701007  160 E4 

可能需要注意:每行被掃描3次,正則表達式電話是昂貴,因此根據數據量需要加載此可能不適合您的情況。