业务方要求将pg中的一个表导入sqlserver,表约1000万行。测试了几种常用的导入导出方法,有成功也有失败的。
一、 pg导出为sql文件,sqlserver中执行
如果没有用到特殊数据类型或者字符,数据量也比较小,这种方法一般是可以的。
1. pg导出
里面会有建表、建索引、授权等语句,需要处理一下,或者可以用 --data-only选项。
pg_dump -d dbname -U username -t tablename --inserts > tablename.sql
2. sqlserver导入
根据文件大小分为三种情况:
- 10M以下:直接用SSMS打开,执行即可
- 10~200M:这时用SSMS打开可能会很慢,或者SSMS直接崩溃,可以使用sqlcmd执行sql文件(类似sqlplus 的 @xx.sql)
#cd到文件所在目录
sqlcmd -i xxx.sql -d dbname
- 200M以上:执行会占用大量内存,可能挤压sqlserver可用内存,影响业务,不推荐使用该方法。
在测试环境执行的时候2G的sql文件执行占用内存超过15G(并且还在往上涨)
二、 pg导出为csv文件,sqlserver用bulk insert
测试bulk insert效率很高,960万行数据执行约53秒,对内存影响也不大。
1. pg导出
psql -d dbname
\copy (select * from xxx) to '/tmp/xxx.csv' DELIMITER ',' CSV;
2. 换行符格式转换
大多数pg装在Linux,sqlserver装在windows,所以要特别注意换行符的问题,否则执行bulk insert的时候会报错第一行最后一列过长,因为它识别不到换行符,把后面的所有数据都当做第一行最后一列。
#Linux格式转windows
sed -e 's/$/\r/' 1pnet.txt >dos.txt
3. sqlserver导入
BULK INSERT 库名..表名
FROM 'c:\test.csv'
WITH (
FIELDTERMINATOR = ',', ---分隔符
ROWTERMINATOR = '\n' ---换行符
)
三、 pg导出为csv文件,sqlserver导入导出向导
第一步同上,第二步使用sqlserver导入导出向导,导入类型选择“平面文件”,定义列名及类型。
但说实话导入导出向导经常会遇到奇奇怪怪的报错,而且搜不到啥好的解决方法,本次遇到报错如下
根据搜到的文章说是字符集问题,但检查导入表里并没有特别字符,改换导入时选择的字符集后也无效,暂未找到解决方法
四、 pg导出为csv文件,sqlserver用bcp导入
第一步同上,第二步使用BCP导入
参考