環境
SQL Server 2012 + CentOS 6.3
問題描述
只具有生產庫的登錄、查詢、創建臨時表權限,缺失導入數據(比如Excel文件、txt文檔、sql腳本等等)權限,需要創建臨時表,插入測試數據。
問題模擬
由於生產庫的數據是敏感數據,並且數據量非常大,當然不能提供出來。這裏只是對這個問題進行一個模擬。數據量少和數據量大操作方法是一樣的。
問題解決
我們可以這樣:
這是Excel中的源數據,如圖1:
圖1 Excel 源數據
Step 1,首先把源數據(Excel中的數據)拷貝出來,或者另存爲csv文件(以逗號作爲分隔),然後重命名後綴爲txt。這裏的文件名假設爲source.txt,然後把行首標題去掉;
6789,Robin,朱二,成都 1234,justdb,張三,瀘州 4567,HelloWorld,李四,廣州 5678,CSDN Blog,王五,中山 1331,Wen,鄧六,深圳 3142,Wentasy,徐七,長沙 4131,Fantasy,燕八,昆明
Step 2,源數據準備好了,那現在我們切換到Linux環境下開始對數據進行處理。觀察源數據中有四列數據,那麼我們需要分隔數據。這裏採用awk處理。代碼如下:
#-F表示以逗號作爲分隔,把源數據中的每列分別保存爲新的四個文件
awk -F","'{print $1}' source.txt > source1.txt
awk -F","'{print $2}' source.txt > source2.txt
awk -F","'{print $3}' source.txt > source3.txt
awk -F","'{print $4}' source.txt > source4.txt
源數據如下:
[root@robin opt]# cat source.txt
1234,justdb,張三,瀘州 4567,HelloWorld,李四,廣州 5678,CSDN Blog,王五,中山 1331,Wen,鄧六,深圳 3142,Wentasy,徐七,長沙 4131,Fantasy,燕八,昆明
操作結果:
[root@robin opt]# cat source1.txt
1234 4567 5678 1331 3142 4131
效果如圖2:
圖2 Step 2 效果圖
Step 3,考慮到這些數據都是基於文本存儲的,那麼INSERT插入時需要在值的首尾加上單引號或者雙引號。代碼如下:
#^表示行首,此行代碼表示在每行的行首加上yy,注意此處添加的內容不要和正文文本相同;
sed 's/^/yy/g'source1.txt –i
#$表示行尾,此行代碼表示在每行的行尾加上zz,同理,意此處添加的內容不要和正文文本相同
sed 's/$/zz/g'source1.txt –i
#把行首的yy替換成單引號
sed"s/yy/\'/g" source1.txt –i
#把行尾的zz替換成單引號
sed"s/zz/\'/g" source1.txt –i
#說明:讀者也可以把行尾和行首替換爲相同的內容,那把替換後的內容再替換爲單引號就只需要執行一行代碼即可。
#這裏只演示一個文本,其餘文本操作方法相同。
操作結果如下:
[root@robin opt]# cat source1.txt
yy1234zz yy4567zz yy5678zz yy1331zz yy3142zz yy4131zz
[root@robin opt]# cat source1.txt
'1234' '4567' '5678' '1331' '3142' '4131'
效果如圖3:
圖 3 Step 3效果圖
Step 4,我們得到每列帶單引號的文本,但是我們需要把這四個文件的每列放到一個文件中,就像炒青椒肉絲,把切好的瘦肉絲、佐料、青椒放到鍋裏炒一樣。我們可以採用如下方法合併文件,使用paste命令,命令如下:
#此命令表示以逗號作爲分隔,合併經過上述處理的四個文件,並保存到結果文件
paste -d ","source1.txt source2.txt source3.txt source4.txt > result.txt
操作結果如下:
[root@robin opt]# cat result.txt
'1234','justdb','張三','瀘州' '4567','HelloWorld','李四','廣州' '5678','CSDN Blog','王五','中山' '1331','Wen','鄧六','深圳' '3142','Wentasy','徐七','長沙' '4131','Fantasy','燕八','昆明'
效果如圖4:
圖4 Step 4效果圖
Step 5,將得到的結果進行最後的處理。我們在行尾加入INSERT語句,這裏假設後面創建的臨時表名稱爲##temp,在行尾加上括號和分號,語句如下:
sed 's/^/INSERT INTO ##tempVALUES(/g' result.txt -i
sed 's/$/);/g'result.txt -i
操作結果如下:
[root@robin opt]# cat result.txt
INSERT INTO ##temp VALUES('1234','justdb','張三','瀘州'); INSERT INTO ##temp VALUES('4567','HelloWorld','李四','廣州'); INSERT INTO ##temp VALUES('5678','CSDN Blog','王五','中山'); INSERT INTO ##temp VALUES('1331','Wen','鄧六','深圳'); INSERT INTO ##temp VALUES('3142','Wentasy','徐七','長沙'); INSERT INTO ##temp VALUES('4131','Fantasy','燕八','昆明');
效果如圖5:
圖5 Step 5效果圖
Step 6,創建臨時表,語句如下:
CREATE TABLE ##temp
(
ID CHAR(16) NOT NULL,
EName VARCHAR(20),
CName VARCHAR(40),
City VARCHAR(20)
);
Step 7,打開SQLServer的查詢分析器,然後執行創建臨時表的語句和插入數據的語句。
執行結果如圖6:
圖6 插入數據效果
其他說明
1.如果文件中每行的末尾出現空格,我們可以使用此命令把空格去掉:
sed 's/\ \+$//'source1.txt –i
2.如果文件中出現^M,我們可以使用此命令將^M去掉:
sed 's/^M//g'source_4.txt –i
3.本文只是簡單的模擬,數據量小不能體現這種方法的優越性,如果數據量大,那給你帶來的是質的飛躍;
4.本文中Step3可以簡化,直接在每列的行首和行尾加入INSERT和括號,但是這樣只是行首和行尾OK了,每個字符串還是沒有用單引號括起來,可以把每行作爲一個單元,然後加入單引號,而不是本文的將每個列分隔出來;
5.本文還想告訴讀者的是多使用Linux吧,並且學會一門腳本語言,這會讓你的工作事半功倍;
6.本文是基於沒有導入數據的權限的情況下做的,如果有該權限,自然很簡單,如果沒有,那本文還是很有參考價值。其實本文提供的就是一種思路,如何把問題拆分、如何巧妙的拼接文本。使用到的核心技術就是Linux的Shell,比如awk、sed的用法。
最終的一鍵腳本
#!/bin/bash
#FileName:auto_import_data.sh
#Desc:Auto Import DataTo MS SQL
#Date:2014-3-14 17:53:12
#Author:Robin
#1.分離數據
awk -F","'{print $1}' source.txt > source1.txt
awk -F","'{print $2}' source.txt > source2.txt
awk -F","'{print $3}' source.txt > source3.txt
awk -F","'{print $4}' source.txt > source4.txt
#2.在行首和行尾添加單引號
sed 's/\ \+$//'source1.txt -i
sed 's/^/yy/g'source1.txt -i
sed 's/$/zz/g'source1.txt -i
sed"s/yy/\'/g" source1.txt -i
sed"s/zz/\'/g" source1.txt -i
sed 's/^/yy/g'source2.txt -i
sed 's/$/zz/g'source2.txt -i
sed "s/yy/\'/g"source2.txt -i
sed"s/zz/\'/g" source2.txt -i
sed 's/^/yy/g'source3.txt -i
sed 's/$/zz/g'source3.txt -i
sed"s/yy/\'/g" source3.txt -i
sed"s/zz/\'/g" source3.txt -i
sed 's/^/yy/g'source4.txt -i
sed 's/$/zz/g'source4.txt -i
sed "s/yy/\'/g"source4.txt -i
sed"s/zz/\'/g" source4.txt -i
#3.合併文件
paste -d ","source1.txt source2.txt source3.txt source4.txt > result.txt
#4.拼接爲最終的插入語句
sed 's/^/INSERT INTO ##tempVALUES(/g' result.txt -i
sed 's/$/);/g'result.txt -i
我的郵箱:[email protected] 新浪微博:@jutdb 微信公衆平臺:JustOracle(微信號:justoracle) 數據庫技術交流羣:336882565(加羣時驗證 From CSDN XXX) All is well 2014年3月15日 By Robin Wen
@Wentasy 博文僅供參考,歡迎大家來訪。如有錯誤之處,希望批評指正。原創博文如需轉載請註明出處,謝謝 :) [CSDN博客] |