2021年7月1日 星期四

[MS sql server] 使用 Sql 語法在不同 database 中間倒資料的方法

 在登入一個 sql server下,

可以用以下語法存取另一個 sql  server,

例如以下語法可以登入名為 xxxServer, port 為 1300 的 sql server 

exec sp_addlinkedserver 'myXxxServer', '', 'SQLOLEDB', 'xxxServer,1300'  -- create linked server to xxxServer
exec sp_addlinkedsrvlogin 'myXxxServer', 'false',null, '{帳號}', '{密碼}' -- login xxxServer

然後就可以用 myXxxServer 這個名字 (可自取) 存取 xxxServer,

例如讀取其中的一個名為 xxxTable 的 table,其 table 在名為 xxxDatabase 的 database 中:

SELECT *
FROM myXxxServer.xxxDatabase.dbo.xxxTable 

還可以做到跨 sql server 的 JOIN 等操作,非常方便,例如:

SELECT *
FROM myXxxServer.xxxDatabase.dbo.xxxTable A INNER JOIN
someTable B ON A.a = B.b

或是倒資料,例如:

INSERT INTO A(a1, a2)
SELECT b1, b2
FROM myXxxServer.xxxDatabase.dbo.B

最後再用以下語法登出 xxxServer

exec sp_dropserver 'myXxxServer', 'droplogins' -- free myXxxServer linked server


**補充:

如果要倒的資料欄位裡有主鍵 (Primary Key),

需要把禁止修改主鍵的功能關掉,Update 資料完後再開回來。

再來此時不能用星號 "*" 來代表所有欄位,要把欄位名稱一個個寫出來才能成功寫入。

例如:

SET IDENTITY_INSERT A ON;

INSERT INTO A(a1, a2)
SELECT b1, b2
FROM myXxxServer.xxxDatabase.dbo.B


SET IDENTITY_INSERT A OFF;


如果想要快速的得到欄位名稱的字串,可以用以下語法來得到
(以下為得到名為 A 這個 table 的所有欄位名稱,會用逗號分隔欄位名,最後用成一串字來輸出):

SELECT SUBSTRING(
    (
	SELECT ', ' + QUOTENAME(COLUMN_NAME)
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'A'
        ORDER BY ORDINAL_POSITION
        FOR XML path('')
    )
    , 3, 200000
)

執行結果就像是: [a1], [a2], [a3]