在計算機審計的數據準備階段,首先需要從被審計單位數據庫抽取數據,轉換加工,然后才能加載到審計數據庫使用。在被審計單位數據庫與審計數據庫之間無法直接連接,或者受異構數據庫格式不兼容的影響丟失數據甚至出錯的情況下,就需要使用第三方的文件存儲作為過渡,通用的過渡載體是文本格式文件。目前,可視化的數據庫文本加載工具主要有DTS、SSIS等,還不能針對指定目錄批量加載數據,而手工對文本文件逐個進行加載,不僅處理效率低下,而且增加了數據質量風險。為了彌補這方面的不足,筆者引入BCP工具。BCP是大容量復制程序的簡稱,是Sybase和Microsoft的數據庫管理系統附帶工具,專用于數據庫表一級數據高效快速地復制,適用于數據庫文件與文本文件格式之間批量轉換,在DOS命令提示符下執行。在計算機審計中,最常見的用途就是把大量的文本數據通過BCP批量導入到Microsof SQL Server空表中。
一、BCP的語法簡要范例
Microsoft SQL Server幫助文件中介紹了一個文本數據導入的范例:
bcp \"Northwind.Jane Doe.Jane's Orders\" out \"Jane's Orders.txt\" -c -q -U \"Jane Doe\" -P \"go dba\"
其含義是把Norhwind數據庫下Jane Doe所擁有的Jane's Orders表導出到本目錄下的Jane's Orders.txt文件內,使用于符型格式輸出,登陸數據庫的權限是Jane Doe用戶,登陸密碼是godba,由于引號內含有空格,所以使用“-q”參數,其他使用默認的字段間逗號分隔,行間回車換行分隔。
而我們在實際工作中,經常會碰到逗號或者回車換行出現在某字段內,比如審批意見等字段甚至還會偶然遇到“|”豎線,另外繁體字和半個字符等數據也會引起文本文件導入的錯誤,超過了范例的使用范圍,這就需要對BCP的參數詳細了解,完整的BCP語法如下:
Bcp{[[database_name.][schema].]{table_name|view_name}|\"query\"}
Bcp{in|out|queryout|format}data_fle
Bcp[-m max_errors][-f format_fie][-x][-e err_fie]
Bcp[-F first_row][-L last_row][-b batch_sie]
Bcp[-n][-c][-N][-w][-V(70|80|90)]
Bcp[-q][-C{ACP|OEM|RAW|code_page}]
[-tfeld_term]
Bcp[-r row_term][-i input_fle][-o output_fle]
[-a packet_size]
Bcp[-S server_name[\\instance_name]][-U login_id]
[P password]
Bcp[-T][-v][-R][-k][-E][-h\"hint[,…n]\"]
根據Transact-SQL語法關系圖的規則,大括號中的部分是必選項,中括號內是可選項,\"|\"是并列關系其中選一的意思。在這些參數中,計算機審計需要掌握的有十個,分別是:-m-e-b-c-t-r-o-S-U-P。
二、實際工作中遇到的問題
由于字段格式不兼容等原因,經常會導致被審計單位數據庫某表格無法正常裝入審計數據庫,如我們在最近一次審計數據準備階段就遇到了這種問題。我們取得了被審計單位導出的文本格式數據,發現中間某些字段有亂碼導致無法正常裝入審計數據庫,樣本如下表。我們仔細研究了表格數據存放的格式,發現出現亂碼的字段是出現在“意見1”、“意見2”、“意見3”和“意見4”,了解其字段含義得知一個超長文本的中文字符串格式意見書被切割為四份,每個包含250個字符,如果意見書中有半角字符出現,那么在第250位字符切割的時候就會把最后一位中文字符切割為兩半,這就是從被審計單位數據庫中導出的文本文件出現亂碼的原因。原因找到了,假設采用通常的字段對應字段導入方式,那么在處理到第250位是半個中文字符的時候會自動與緊接著的分隔符結合形成新的字符串,這樣字段的對應關系就被打亂了。

三、解決方案
我們分為兩個階段完成,第一階段是被審計單位數據庫表一級數據BCP導出文本的過程,第二階段是把文本文件裝入到審計數據庫的過程,介紹的重點放在第二階段。
第一階段:建立被審計單位數據庫導出文本的腳本。
第一步,建立一個視圖V_ALCHECKADV把原表的四個字段通過位運算連接起來,參照腳本如下:
create view V_ALCHECKDV as select 申請書編碼,順序號,意見順序號,意見1+意見2+意見3+意見4 as 意見書,操作員代碼,操作日期 from ALCHECKDV;
第二步,定義字段分割符號和行分隔符用以區別意見書內部可能包含的\"回車、換行、豎線、制表符\"等內容,本例選擇字段分割使用\"|!\",行分割使用\"|@\\",(\"\\r\"的含義是回車,\"\\"的含義是換行),語句如下:
bcp \"ALCHECKADV.dbo. V_ALCHECKADV\" out \"E:\\V_ALCHECKD.datc\"-m 0 -e \"E:\\alcheckad.datc_error.txt\"-m 10000 -e \"E:\\貸款意見表\\01alcheckadv20090430.datc_error1.txt\" -c -t\"|!\" -b 10000 -r\"|@\" -U \"sa\" -P\"\";
其含義是把ALCHECKADV數據庫下dbo用戶的V_ALCHECKADV視圖(或表)導出存放為E盤下的V_ALCHECKAD.datc,每10000行提交一次校驗,執行過程中沒有被正常導入的文件輸出存放到E盤下的alcheckad.datc error.txt,使用字符型格式輸出,\"|!\"分割字段,\"|@\\"換行,用戶名sa,密碼為空。
把上述腳本交由被審計單位系統管理員去測試運行,提取數據。
第二階段:建立審計單位數據庫文本導入的腳本。
第一步:建立等同于被審計單位V_ALCHECKADV等同的表,把字符型數據調增寬度,比如char(250)變更為nvarchar(5000)以提高容錯率,即使是在連續五行字段分隔符識別錯誤的情況下正常導入。
第二步:提取文本文件目錄下所有文件的全名。
E:\\貸款意見表\\DATAl>dir>list.txt
第三步:使用ultraedit的塊復制功能把文件列表的全名復制島出來,直接粘貼到EXCEL中,然后使用拖拉工具填充最終在F2形成批處理腳本:
BCP \"ALCHECKADVdbo.ALCHECKDV\" in \"E:\\貸款意見表\\DATAl\\22alcheckadv.datc\" -m 10000 -e \"E:\\貸款意見表\\DATAl\\error\\22alcheckadv.datc_error.txt\" -c -t\"|!\" -b 10000 -r\"|@\" -U \"sa\" _P\"\";

第四步:拷貝F2列粘貼到記事本中另存為“bcp_sql.bat”批處理文件。
第五步:切換到BCP目錄路徑執行下列語句。
C:\\Program Files\\Microsoft SQL Server\\80\\Tools
Binn>bcp_sqlbat > E:\\貸款意見表DATAl\\screencopy.txt
四、注意事項
(一)在計算機審計時使用BCP工具主要因素是大批量的文本導入,結果正確和運行穩定是第一位的,所以不建議使用“-f”、“queryout”、“-o”等特殊定義的參數,原因如下:不用“-f”是因為格式文件比較復雜,修改起來也比較繁瑣,不如編寫語句直觀高效;不用“queryout”時因為嵌入SQL語句比較凌亂,而且其功能完全可以由新建視圖代替;不用“-o”是因為批處理需要指定每一個路徑,而實際操作中只需要一個匯總的日志,所以在DOS批處理命令行后加上“>某日志.TXT”足以代替它。
(二)綜合使用Ularedit、Excel等工具發揮其文本編輯的各自優勢,Ularedit在打開大文本文件編輯半個中文字符等亂碼、繁體字和文本塊復制方面有優勢,而Excel具備的函數編輯功能儼和文本選擇性粘貼等功能使其在批處理命令編輯方面有優勢。
(三)由于BCP執行過程需要運行sql server目標服務器,建議先挑選較小的文本測試腳本運行成功后,在生成批處理文件提交到服務器上夜間運行以減輕系統壓力。(作者單位:陜西省寧強縣審計局)