MySQL--將MySQL數據導入到SQL Server


隨着時代的進步,社會的發展,各種技術層出不窮五花八門亂七八糟數不勝數(寫作文呢!!!)

不扯廢話,簡單而言,很多公司都會同時使用多種數據庫,因此數據在不同數據庫之間導入導出就成為一個讓人蛋疼的問題,對於周期行的需求,可以開發專門的程序處理,但是對於偶爾不確定性的需求,就到了需要DBA獻身的時候啦,當需要將MySQL數據導入到SQL Server中時,該怎么搞呢?

當然使用工具最簡單,但是我就忽略工具!!!

在MySQL中創建測試數據:

create table tb001(c1 int auto_increment primary key,c2 varchar(2000));
insert into tb001(c2) select 'abc\r\n';
insert into tb001(c2) select '你好啊\r\n';
insert into tb001(c2) select '你好啊\n';
insert into tb001(c2) select '雙引號"';
insert into tb001(c2) select '全角雙引號“';
insert into tb001(c2) select '單引號''';
insert into tb001(c2) select '全角單引號’';

##=====================================================================##
使用mysqldump來導出與MS SQL SERVER兼容的INSERT 語句:

mysqldump --host='192.168.166.169' --port=3358 --user='mysql_admin' --password='mysql@Admin@Pwd' --skip-add-locks --compatible=mssql --complete-insert --compact --extended-insert=false --default-character-set=utf8 -t --databases 'test' --table 'tb001' >/tmp/t4.sql

上面腳本的一些注釋說明:

--compatible=mssql ##導出的SQL與MS SQL Server兼容
--complete-insert ##導出的INSERT語句包含列名
--compact ##采用精簡模式,不輸出各種MySQL信息
--extended-insert=false ##采用一行數據一條INSERT的方式
--default-character-set=utf8 ##指定導出的字符集
-t ##-t表示只導出數據,-d表示只導出數據結構
--databases 'test' ##數據庫名稱
--table 'CityMatchup' ##表名

導出結果為:

INSERT INTO "tb001" ("c1", "c2") VALUES (1,'abc\r\n');
INSERT INTO "tb001" ("c1", "c2") VALUES (2,'你好啊\r\n');
INSERT INTO "tb001" ("c1", "c2") VALUES (3,'你好啊\n');
INSERT INTO "tb001" ("c1", "c2") VALUES (4,'雙引號\"');
INSERT INTO "tb001" ("c1", "c2") VALUES (5,'全角雙引號“');
INSERT INTO "tb001" ("c1", "c2") VALUES (6,'單引號\'');
INSERT INTO "tb001" ("c1", "c2") VALUES (7,'全角單引號’');

對於列名用雙引號的問題,可以使用SET QUOTED_IDENTIFIER ON 來處理,也可以使用SQLCMD加-I參數來處理
但是對文本中的單引號就無解了,MySQL中使用"\"來作為轉義符,而SQL Server中使用兩個單引號來表示一個單引號。

MySQLdump可以將數據導成INSERT語句,並提供配置兼容其他數據庫的參數,但由於不同數據庫轉義字符不同,因此即使使用compatible=mssql也不能保證導出的腳本能在SQL Server中正常執行。

##===========================================================================##

使用SELECT INTO OUTFILE來導出數據

SELECT * INTO OUTFILE '/tmp/tb001.txt' 
FIELDS TERMINATED BY '||--||' 
LINES TERMINATED BY '||==||' FROM test.tb001;

在Linux下看到的是這樣:

雖然有點亂,但是忍啦!

然后下載文件,使用notepad++打開,選擇“格式”>> "轉為ANSI編碼格式" ,然后另存為新文件,在SQL Server中使用BULK INSERT來導入:

CREATE TABLE tmp_tb001(id NVARCHAR(2000),c1 NVARCHAR(2000))
GO
BULK INSERT tmp_tb001
FROM 'D:\tb002.txt'
WITH(FIELDTERMINATOR='||--||',
ROWTERMINATOR='||==||'
)
GO
SELECT * FROM tmp_tb001

也可以使用SQL Server的導入導出工具來處理,主要修改分隔符。

注意使用SELECT INTO OUTFILE導出文件時,NULL值被表示為\N,而\N在導入SQL Server時會被當初字符串“\N”來處理,因此建議先建立一個完全由NVARCHAR類型列組成的表來“暫存”導入的時候,然后經過數據清理后再導入正式表中,對於懶與一列一列折騰的人來說,可以拼下SQL來獲取表的所有列轉換:

SELECT 
'CASE WHEN ['+T1.name+']=''\N'' THEN NULL ELSE ['+T1.name+'] END AS ['+T1.name+'],'
FROM sys.all_columns T1
WHERE T1.object_id=OBJECT_ID('tmp_tb001')

由於我們強行將\N當成NULL來轉換,難免會造成誤傷,將真實數據就為’\N‘的值變為NULL,因此導完數據后檢查是必須的。

最后語句為:

SELECT 
CASE WHEN [id]='\N' THEN NULL ELSE [id] END AS [id],
CASE WHEN [c1]='\N' THEN NULL ELSE [c1] END AS [c1]
FROM tmp_tb001

執行結果為:

##=======================================================================##

導出INSERT腳本存在轉義字符單引號的問題,同時導出數據不包含GO,在需要大量數據導入到SQL SERVER時存在嚴重的性能問題,可以嘗試參考本人的《Powershell--批量拆分SQL語句為事務並批處理》來處理,但也是問題多多。

而導出文件然后導入的方式,需要對文件進行一次轉換,文件較大時notepad++可能無法打卡,UE能稍微給力點,但面對好幾個G的文本文件也是無力回天,同時NULL值處理也需要慎重對待。

##========================================================================##

好啦,是時候上妹子啦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM