一次解決DB2接口文件到Oracle無法導入問題的經歷

前幾天觸點營銷平臺出了點問題,請同事幫忙處理,結果兩天過去了,還是沒定位到問題。
臨近春節,還是要把問題解決掉的,今天忙碌了一上午總算解決這個問題
DB2主機往Oracle主機發送接口文件,接口文件的數據總是缺失一部分,導致CRM系統無法看到相應的營銷活動。
於是你說我沒傳接口文件,我說你沒法處理接口文件,其實也很容易處理,關鍵是一個扯字,呵呵,看下接口文件是否在服務器上以及是否與兩端的數據庫一致即可。
好不容易釐清了接口文件問題,又扯到接口文件本身內容的問題,從接口機上看到的文件部分內容是亂碼,且存在回車換行問題。
又開始了新一輪的測試,其實兩端都應該測試接口文件能否正常入庫,在DB2上測試數據的導出和導入都是正常的,那接口主機上看到的亂碼是什麼情況呢?估計數行字節太長,導致無法全部展示,所以系統把部分中文字符給分割了,導致看到的文件內容是亂碼。
在DB2上的測試很簡單,導出數據,加載數據,展示數據即可。
export to u:/IW3001test0001.AVL of del modified by coldel0x01 nochardel striplzeros decplusblank
select * from hnwangbq.yingxiaoan;
create table hnwangbq.test
(
sale_act_id varchar(20),
sale_act_name varchar(50),
act_begin_date varchar(20),
act_end_date varchar(20),
data_time varchar(20),
sale_act_script varchar(500),
sms_script varchar(500),
sale_act_type varchar(20)
);
import from u:/IW3001test0001.AVL of del modified by coldel0x01 nochardel decplusblank
insert into hnwangbq.test;
select * from hnwangbq.test;
在DB2上處理的一切都很正常,接下來測試在Oracle上的導入。
沒辦法只得重新安裝了一下Oracle和PL/SQL Developer,創建新表。
create table hnwangbq.test
(
sale_act_id varchar2(20),
sale_act_name varchar2(50),
act_begin_date varchar2(20),
act_end_date varchar2(20),
data_time varchar2(20),
sale_act_script varchar2(500),
sms_script varchar2(500),
sale_act_type varchar2(20)
);
通過PL/SQL Developer的Text importer進行導入測試,發現報錯是字段行太短,接下來繼續查看發現Oracle把幾條記錄給合併到一條記錄中了
爲什麼出現這種情況呢,發現行中存在"雙引號情況,Oracle把"雙引號作爲列的Quote character,所以把兩個"雙引號中的內容作爲一個字段了
於是通過replace函數把"雙引號改爲'單引號,再次測試,搞定
不過在生產環境的測試又出現問題了,還是出現錯誤,經過閱讀shell腳本發現Oracle是通過SQLLDR進行接口文件加載的,我也通過SQLLDR進行了測試,控制文件如下:
LOAD DATA                                                          
INFILE 'd:\IW3001test0001.AVL'                                      
REPLACE INTO TABLE test          
FIELDS TERMINATED BY X'01'  OPTIONALLY ENCLOSED BY '"'  
trailing nullcols                                                  
(SALE_ACT_ID   ,                                                    
SALE_ACT_NAME  ,                                                    
ACT_BEGIN_DATE ,                        
ACT_END_DATE   ,                        
DATA_TIME      ,                        
SALE_ACT_SCRIPT ,                                                    
SMS_SCRIPT     ,                                                    
SALE_ACT_TYPE                                                      
)  
發現也是報錯誤,錯誤的原因在加載日誌中,錯誤信息如下:
記錄 1: 被拒絕 - 表 TEST 的列 SALE_ACT_SCRIPT 出現錯誤。
數據文件的字段超出最大長度
記錄 3: 被拒絕 - 表 TEST 的列 SMS_SCRIPT 出現錯誤。
數據文件的字段超出最大長度
記錄 8: 被拒絕 - 表 TEST 的列 SMS_SCRIPT 出現錯誤。
數據文件的字段超出最大長度
記錄 11: 被拒絕 - 表 TEST 的列 SMS_SCRIPT 出現錯誤。
。。。
記錄 42: 被拒絕 - 表 TEST 的列 SMS_SCRIPT 出現錯誤。
數據文件的字段超出最大長度
表 TEST:
 27 行 加載成功。
 由於數據錯誤, 15 行 沒有加載。
 由於所有 WHEN 子句失敗, 0 行 沒有加載。
 由於所有字段都爲空的, 0 行 沒有加載。
通過百度搜索了一下,發現其他人也有同樣的問題,問題的原因在Oracle的SQLLDR在缺省的情況下對字符串的處理是CHAR(255),而部分字段的列顯然超過了255個字節,於是修改了一下控制文件。
LOAD DATA                                                          
INFILE 'd:\IW3001test0001.AVL'                                      
REPLACE INTO TABLE test          
FIELDS TERMINATED BY X'01'  OPTIONALLY ENCLOSED BY '"'  
trailing nullcols                                                  
(SALE_ACT_ID   ,                                                    
...                      
SALE_ACT_SCRIPT char(2000),                                                    
SMS_SCRIPT   char(2000),
其實解決方案不外乎兩個,一個方法是在數據源側上進行控制,一個方法是在加載側進行不停的測試和完善。

問題的解決之道無它,無非是測試+測試而已,有時候看似解決了一個問題,另外一個問題又出來了,問題的根源在於不停的探索。
其實探索也是一種樂趣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章