环境
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.txtawk -F","'{print $2}' source.txt > source2.txtawk -F","'{print $3}' source.txt > source3.txtawk -F","'{print $4}' source.txt > source4.txt
源数据如下:
[[email protected] opt]# cat source.txt
1234,justdb,张三,泸州4567,HelloWorld,李四,广州5678,CSDN Blog,王五,中山1331,Wen,邓六,深圳3142,Wentasy,徐七,长沙4131,Fantasy,燕八,昆明
操作结果:
[[email protected] opt]# cat source1.txt
123445675678133131424131
效果如图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 #说明:读者也可以把行尾和行首替换为相同的内容,那把替换后的内容再替换为单引号就只需要执行一行代码即可。#这里只演示一个文本,其余文本操作方法相同。
操作结果如下:
[[email protected] opt]# cat source1.txt
yy1234zzyy4567zzyy5678zzyy1331zzyy3142zzyy4131zz
[[email protected] 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
操作结果如下:
[[email protected] 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 -ised 's/$/);/g'result.txt -i
操作结果如下:
[[email protected] 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和括号即可;
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.txtawk -F","'{print $2}' source.txt > source2.txtawk -F","'{print $3}' source.txt > source3.txtawk -F","'{print $4}' source.txt > source4.txt #2.在行首和行尾添加单引号sed 's/\ \+$//'source1.txt -ised 's/^/yy/g'source1.txt -ised 's/$/zz/g'source1.txt -ised"s/yy/\'/g" source1.txt -ised"s/zz/\'/g" source1.txt -i sed 's/^/yy/g'source2.txt -ised 's/$/zz/g'source2.txt -ised "s/yy/\'/g"source2.txt -ised"s/zz/\'/g" source2.txt -i sed 's/^/yy/g'source3.txt -ised 's/$/zz/g'source3.txt -ised"s/yy/\'/g" source3.txt -ised"s/zz/\'/g" source3.txt -i sed 's/^/yy/g'source4.txt -ised 's/$/zz/g'source4.txt -ised "s/yy/\'/g"source4.txt -ised"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 -ised '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博客] |