การเลือกข้อมูลจากเซิร์ฟเวอร์สองเครื่องที่แตกต่างกันใน SQL Server


363

ฉันจะเลือกข้อมูลในแบบสอบถามเดียวกันจากฐานข้อมูลที่แตกต่างกันสองแห่งที่อยู่บนเซิร์ฟเวอร์สองแห่งใน SQL Server ได้อย่างไร


6
คำตอบจาก Eric และ Raging Bull มีประโยชน์มาก ฉันสามารถใช้สิ่งนี้เพื่อคัดลอกปริมาณข้อมูลจำนวนมากจาก DEV ถึง PROD ลดเวลาตั้งแต่อยู่ระหว่าง 5 ชั่วโมงถึง 18 ชั่วโมงลดลงถึง 17 วินาที
Chris Aldrich

@ Eric รุ่งโรจน์สำหรับการแก้ไขคำถามคลุมเครือเล็กน้อยและทำให้มันเป็นคำถามที่ 170 ตัวแทน :)
เอริควู

คำตอบ:


345

สิ่งที่คุณกำลังมองหาคือเซิร์ฟเวอร์ที่เชื่อมโยง คุณสามารถเข้าถึงได้ใน SSMS จากตำแหน่งต่อไปนี้ในแผนผังของ Object Explorer:

Server Objects-->Linked Servers

หรือคุณสามารถใช้sp_addlinkedserver sp_addlinkedserver

คุณต้องตั้งค่าหนึ่งเท่านั้น เมื่อคุณมีแล้วคุณสามารถเรียกตารางบนเซิร์ฟเวอร์อื่น ๆ เช่น:

select
    *
from
    LocalTable,
    [OtherServerName].[OtherDB].[dbo].[OtherTable]

โปรดทราบว่าเจ้าของไม่ได้อยู่เสมอdboดังนั้นโปรดแทนที่ด้วยสคีมาที่คุณใช้


13
เราสามารถทำได้โดยไม่ต้องเชื่อมโยงเซิร์ฟเวอร์
Steam

5
@Eric วัตถุเซิร์ฟเวอร์ใน SSMS อยู่ที่ไหน
Tsahi Asher

9
@TsahiAsher - เมื่อคุณเชื่อมต่อกับเซิร์ฟเวอร์ Server Objects เป็นโฟลเดอร์ในแผนผังของ Object Explorer
เอริค

2
หากไม่ทราบคุณสามารถละเว้นสคีมาเพื่อใช้ค่าเริ่มต้นได้ เช่น[OtherServerName].[OtherDB]..[OtherTable]อย่างไรก็ตามจะเป็นการดีที่สุดหากรวมไว้
Tom Bowers

92

คุณสามารถทำได้โดยใช้เซิร์ฟเวอร์ที่มีการเชื่อมโยง

โดยทั่วไปแล้วเซิร์ฟเวอร์ที่ลิงก์จะได้รับการกำหนดค่าให้เปิดใช้งานโปรแกรมฐานข้อมูลเพื่อเรียกใช้คำสั่ง Transact-SQL ที่รวมตารางไว้ในอินสแตนซ์อื่นของ SQL Server หรือผลิตภัณฑ์ฐานข้อมูลอื่นเช่น Oracle แหล่งข้อมูล OLE DB หลายประเภทสามารถกำหนดค่าเป็นเซิร์ฟเวอร์ที่เชื่อมโยงรวมถึง Microsoft Access และ Excel

เซิร์ฟเวอร์ที่เชื่อมโยงนำเสนอข้อดีดังต่อไปนี้:

  • ความสามารถในการเข้าถึงข้อมูลจากภายนอกของ SQL Server
  • ความสามารถในการออกแบบสอบถามแบบกระจายอัพเดตคำสั่งและธุรกรรมบนแหล่งข้อมูลที่แตกต่างกันทั่วทั้งองค์กร
  • ความสามารถในการระบุแหล่งข้อมูลที่หลากหลายในทำนองเดียวกัน

อ่านเพิ่มเติมเกี่ยวกับการเชื่อมโยงเซิร์ฟเวอร์

ทำตามขั้นตอนเหล่านี้เพื่อสร้างเซิร์ฟเวอร์ที่เชื่อมโยง:

  1. วัตถุเซิร์ฟเวอร์ -> เซิร์ฟเวอร์ที่เชื่อมโยง -> เซิร์ฟเวอร์ที่เชื่อมโยงใหม่

  2. ระบุชื่อเซิร์ฟเวอร์ระยะไกล

  3. เลือกประเภทเซิร์ฟเวอร์ระยะไกล (SQL Server หรืออื่น ๆ )

  4. เลือกความปลอดภัย -> ทำโดยใช้บริบทความปลอดภัยนี้และระบุการเข้าสู่ระบบและรหัสผ่านของเซิร์ฟเวอร์ระยะไกล

  5. คลิกตกลงและคุณทำเสร็จแล้ว !!

นี่คือบทแนะนำอย่างง่ายสำหรับการสร้างเซิร์ฟเวอร์ที่เชื่อมโยง

หรือ

คุณสามารถเพิ่มเซิร์ฟเวอร์ที่เชื่อมโยงโดยใช้แบบสอบถาม

ไวยากรณ์:

sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ] 
     [ , [ @provider= ] 'provider_name' ]
     [ , [ @datasrc= ] 'data_source' ] 
     [ , [ @location= ] 'location' ] 
     [ , [ @provstr= ] 'provider_string' ] 
     [ , [ @catalog= ] 'catalog' ] 

อ่านเพิ่มเติมเกี่ยวกับsp_addlinkedserver

คุณต้องสร้างเซิร์ฟเวอร์ที่เชื่อมโยงเพียงครั้งเดียว หลังจากสร้างเซิร์ฟเวอร์ที่เชื่อมโยงแล้วเราสามารถค้นหาได้ดังนี้:

select * from LinkedServerName.DatabaseName.OwnerName.TableName

หมายเหตุ: ดูที่นี่สำหรับวิธีมีชื่อเซิร์ฟเวอร์เป็นชื่ออื่นที่ไม่ใช่ชื่อโฮสต์ / พอร์ต
Richard

1
เคล็ดลับนิดหน่อยตรงนี้ถ้าคุณมีปัญหากับ sp_addlinkedserver สร้างเซิร์ฟเวอร์ในกล่องโต้ตอบ - ตรวจสอบให้แน่ใจว่ามันใช้งานได้ - จากนั้นคลิกขวาที่การเชื่อมต่อและเลือก scrip [t เซิร์ฟเวอร์ที่ถูกเชื่อมโยงตามที่สร้าง
Richard Housham

25
SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

นอกจากนี้คุณยังสามารถดูการใช้เซิร์ฟเวอร์ที่เชื่อมโยง เซิร์ฟเวอร์ที่เชื่อมโยงสามารถเป็นแหล่งข้อมูลประเภทอื่นเช่นแพลตฟอร์ม DB2 นี่เป็นวิธีหนึ่งในการพยายามเข้าถึง DB2 จากการเรียก SQL Server TSQL หรือ Sproc ...


2
วิธีนี้จะใช้ได้ตลอดเวลาหรือไม่ สถานการณ์อะไรที่มันอาจล้มเหลว?
Steam

3
ยืนยันสิ่งนี้ล้มเหลวใน env ของฉันข้อผิดพลาดบอกว่าฉันต้องใช้ addlinkedserver
gorlaz

1
ใช้งานได้กับทุกคนโดยไม่ใช้เซิร์ฟเวอร์ที่เชื่อมโยงหรือไม่
Doug S

ทดสอบและได้รับข้อผิดพลาดคือCould not find server '88.208.229.164' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
WhatsThePoint

22

การสืบค้นข้ามฐานข้อมูล 2 แบบคือแบบสอบถามแบบกระจาย นี่คือรายการของเทคนิคบางอย่างรวมทั้งข้อดีและข้อเสีย:

  1. เซิร์ฟเวอร์ที่เชื่อมโยง:ให้การเข้าถึงแหล่งข้อมูลที่หลากหลายกว่าการจำลองแบบ SQL Server
  2. เซิร์ฟเวอร์ที่เชื่อมโยง:เชื่อมต่อกับแหล่งข้อมูลที่การจำลองแบบไม่รองรับหรือต้องการการเข้าถึงแบบเฉพาะกิจ
  3. เซิร์ฟเวอร์ที่เชื่อมโยง: ทำงานได้ดีกว่า OPENDATASOURCE หรือ OPENROWSET
  4. ฟังก์ชันOPENDATASOURCEและOPENROWSET : สะดวกสำหรับการดึงข้อมูลจากแหล่งข้อมูลแบบเฉพาะกิจ OPENROWSET มีสิ่งอำนวยความสะดวกจำนวนมากเช่นกันซึ่งอาจ / อาจไม่ต้องการไฟล์รูปแบบซึ่งอาจเป็นซอ
  5. OPENQUERY : ไม่รองรับตัวแปร
  6. ทั้งหมดเป็นโซลูชั่น T-SQL ใช้งานและตั้งค่าได้ค่อนข้างง่าย
  7. ทั้งหมดขึ้นอยู่กับการเชื่อมต่อระหว่างต้นทางและปลายทางซึ่งอาจส่งผลต่อประสิทธิภาพและความสามารถในการปรับขยาย

OPENQUERY ยังต้องการเซิร์ฟเวอร์ที่เชื่อมโยงซึ่ง OPENDATASOURCE ไม่ต้องการ
CJ

16

ลองนี้:

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=YOUR SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
UNION
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=ANOTHER SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a

16

ทั้งหมดนี้เป็นคำตอบที่ดี แต่อันนี้หายไปและมันมีประโยชน์ใช้สอย อาจเป็นไปได้ว่ามันไม่เหมาะกับสิ่งที่ OP ต้องการ แต่คำถามนั้นคลุมเครือและฉันรู้สึกว่าคนอื่นอาจหาทางมาที่นี่ โดยทั่วไปคุณสามารถใช้ 1 หน้าต่างเพื่อเรียกใช้แบบสอบถามกับเซิร์ฟเวอร์หลาย ๆ ตัวพร้อมกันได้โดยมีวิธีการดังนี้:

ใน SSMS เปิดเซิร์ฟเวอร์ที่ลงทะเบียนและสร้างกลุ่มเซิร์ฟเวอร์ใหม่ภายใต้เซิร์ฟเวอร์กลุ่มภายใน

ภายใต้กลุ่มนี้สร้างการลงทะเบียนเซิร์ฟเวอร์ใหม่สำหรับแต่ละเซิร์ฟเวอร์ที่คุณต้องการสอบถาม หากชื่อ DB แตกต่างกันให้ตั้งค่าเริ่มต้นสำหรับแต่ละชื่อในคุณสมบัติ

ตอนนี้กลับไปที่กลุ่มที่คุณสร้างในขั้นตอนแรกคลิกขวาและเลือกแบบสอบถามใหม่ หน้าต่างแบบสอบถามใหม่จะเปิดขึ้นและแบบสอบถามใด ๆ ที่คุณเรียกใช้จะถูกดำเนินการในแต่ละเซิร์ฟเวอร์ในกลุ่ม ผลลัพธ์จะถูกนำเสนอในชุดข้อมูลเดียวที่มีชื่อคอลัมน์เพิ่มเติมเพื่อระบุว่าเซิร์ฟเวอร์ใดที่ระเบียนนั้นมา ถ้าคุณใช้แถบสถานะที่คุณจะทราบชื่อเซิร์ฟเวอร์จะถูกแทนที่ด้วยหลาย


2
ดูเหมือนว่าจะถือว่าแบบสอบถามใช้ตารางเดียวกันในฐานข้อมูลทั้งหมด (ซึ่งเป็นสิ่งที่ดีสำหรับตารางมาตรฐานเช่น sys.tables แต่ไม่น่าจะเป็นตารางที่สร้างขึ้นเองเช่น dbo.mycustomers)
Dennis Jaheruddin

เนื่องจากเป็น "แบบสอบถามเดียวกันจากฐานข้อมูลที่แตกต่างกันสองแห่ง" มีแนวโน้มสูงที่จะมีตารางเดียวกัน แต่ใช่ฉันใช้วิธีนี้เป็นประจำสำหรับระบบที่ใช้งานจริงซึ่งอยู่ในเซิร์ฟเวอร์หลายเครื่องและสำหรับการสืบค้นตาราง MSDB
พอล

คุณสมบัติสุดยอดจริงๆ ข้อเสียเปรียบคือสคีมาของชุดผลลัพธ์ต้องตรงกันเนื่องจากจะดำเนินการค้นหาสองครั้งและผสานทั้งหมดในเวลาเดียวกัน มันจะดีถ้าคุณสามารถอ้างอิงเซิร์ฟเวอร์ภายใน SQL เองเช่นเดียวกับที่คุณเชื่อมโยงกับเซิร์ฟเวอร์แม้ว่าคุณจะไม่สามารถเข้าร่วมชุดผลลัพธ์และชุดจะต้องถูกสร้างขึ้นเพื่อประเมินแยกต่างหาก
Kross

1
@ เอาชนะคุณได้ สร้างตาราง #output ทำตรรกะตาม @@ SERVERNAME และเติมข้อมูลลงใน #output แล้วลงท้ายด้วยตัวเลือก ฉันทำสิ่งที่คล้ายกันสำหรับการค้นหาข้อมูลบันทึกจากการผสมผสานของเครื่อง SQL2000 และ SQL2008R2 ซึ่งมีระดับ / คอลัมน์ข้อมูลต่างกัน แต่แทนที่จะเป็น @@ SERVERNAME ฉันใช้ตัวแปรรุ่นเซิร์ฟเวอร์
พอล

9

ฉันมีปัญหาเดียวกันในการเชื่อมต่อ SQL_server 2008 กับ SQL_server 2016 ที่โฮสต์ในเซิร์ฟเวอร์ระยะไกล คำตอบอื่น ๆ ไม่ได้ผลสำหรับฉันตรงไปตรงมา ฉันเขียนโซลูชัน tweaked ของฉันที่นี่เพราะฉันคิดว่ามันอาจเป็นประโยชน์สำหรับคนอื่น

คำตอบเพิ่มเติมสำหรับการเชื่อมต่อระยะไกล IP db:

ขั้นตอนที่ 1: ลิงค์เซิร์ฟเวอร์

EXEC sp_addlinkedserver @server='SRV_NAME',
   @srvproduct=N'',
   @provider=N'SQLNCLI',   
   @datasrc=N'aaa.bbb.ccc.ddd';

EXEC sp_addlinkedsrvlogin 'SRV_NAME', 'false', NULL, 'your_remote_db_login_user', 'your_remote_db_login_password'

... SRV_NAMEชื่อที่ประดิษฐ์ เราจะใช้มันเพื่ออ้างถึงเซิร์ฟเวอร์ระยะไกลจากแบบสอบถามของเรา aaa.bbb.ccc.dddเป็นที่อยู่ IP ของเซิร์ฟเวอร์ระยะไกลที่โฮสต์ SQLserver DB ของคุณ

ขั้นตอนที่ 2: เรียกใช้คิวรีของคุณ ตัวอย่างเช่น:

SELECT * FROM [SRV_NAME].your_remote_db_name.dbo.your_table

... และนั่นมัน!

รายละเอียดไวยากรณ์: sp_addlinkedserverและsp_addlinkedsrvlogin


4

สร้างคำนิยามเซิร์ฟเวอร์ที่เชื่อมโยงในเซิร์ฟเวอร์หนึ่งไปยังเซิร์ฟเวอร์อื่น (คุณต้องใช้ SA ในการดำเนินการนี้) จากนั้นเพียงอ้างอิงพวกเขาด้วยการตั้งชื่อ 4 ส่วน (ดู BOL)


4

เซิร์ฟเวอร์ 2008:

เมื่ออยู่ใน SSMS เชื่อมต่อกับ server1.DB1 และลอง:

SELECT  * FROM
[server2].[DB2].[dbo].[table1]

ดังที่คนอื่น ๆ ระบุไว้หากไม่ได้ผลนั่นเป็นเพราะเซิร์ฟเวอร์ไม่ได้เชื่อมโยง

ฉันได้รับข้อผิดพลาด:

ไม่พบเซิร์ฟเวอร์ DB2 ใน sys.servers ตรวจสอบว่าระบุชื่อเซิร์ฟเวอร์ที่ถูกต้อง หากจำเป็นให้ดำเนินการกระบวนงานที่เก็บไว้ sp_addlinkedserver เพื่อเพิ่มเซิร์ฟเวอร์ไปยัง sys.servers

ในการเพิ่มเซิร์ฟเวอร์:

อ้างอิง: เพื่อเพิ่มเซิร์ฟเวอร์โดยใช้การเชื่อมโยง sp_addlinkedserver: [1]: การเพิ่มเซิร์ฟเวอร์โดยใช้ sp_addlinkedserver

หากต้องการดูว่ามีอะไรอยู่ใน sys.servers ของคุณเพียงแค่ค้นหา:

SELECT * FROM [sys].[servers]


2

ในฐานะที่เป็น @ Super9 บอกเกี่ยวกับ OPENDATASOURCE ใช้รับรองความถูกต้องของ SQL Server กับผู้ให้บริการข้อมูล SQLOLEDB ฉันเพิ่งโพสต์ที่นี่ข้อมูลโค้ดสำหรับหนึ่งตารางอยู่ในฐานข้อมูลเซิร์ฟเวอร์ปัจจุบันที่โค้ดทำงานอยู่และอีกอันในเซิร์ฟเวอร์อื่น'192.166.41.123'

SELECT top 2 * from dbo.tblHamdoonSoft  tbl1 inner JOIN  
OpenDataSource('SQLOLEDB','Data Source=192.166.41.123;User ID=sa;Password=hamdoonsoft')
.[TestDatabase].[dbo].[tblHamdoonSoft1] tbl2 on tbl1.id = tbl2.id

0
sp_addlinkedserver('servername')

มันควรจะเป็นแบบนี้ -

select * from table1
unionall
select * from [server1].[database].[dbo].[table1]

0

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันใช้คำพ้องความหมาย สมมติว่ามีการดำเนินการค้นหาภายในเซิร์ฟเวอร์ฐานข้อมูล A และค้นหาตารางในเซิร์ฟเวอร์ฐานข้อมูล B ที่ไม่มีอยู่ในเซิร์ฟเวอร์ A เพิ่มคำพ้องบนฐานข้อมูลที่เรียกตารางจากเซิร์ฟเวอร์ B แบบสอบถามของคุณไม่จำเป็นต้อง รวมสกีมาใด ๆ หรือชื่อฐานข้อมูลที่แตกต่างกันเพียงแค่เรียกชื่อตารางต่อปกติและมันจะทำงาน

ไม่จำเป็นต้องเชื่อมโยงเซิร์ฟเวอร์เนื่องจากคำพ้องความหมายเป็นประเภทของการเชื่อมโยง


1
ตอนนี้ "คำพ้องความหมาย" ในบริบทนี้คืออะไร?
Oskar Berggren

มันเป็นวัตถุฐานข้อมูลที่อ้างถึงวัตถุฐานในฐานข้อมูลอื่น ข้อมูลเพิ่มเติมที่นี่: docs.microsoft.com/en-us/sql/relational-database/synonyms/ …
Niklas Henricson

เยี่ยมฉันไม่ทราบเกี่ยวกับฟีเจอร์นั้น อย่างไรก็ตามคุณระบุว่าพวกเขาหลีกเลี่ยงความต้องการเซิร์ฟเวอร์ที่เชื่อมโยง แต่ฉันไม่สามารถดูได้ ดูเหมือนว่าคำพ้องความหมายจะเป็นคำพ้องความหมายและไม่มีความสามารถในการควบคุมระยะไกลเฉพาะ ในตัวอย่าง B ที่docs.microsoft.com/en-us/sql/t-sql/statements/ ......พวกเขาสร้างเซิร์ฟเวอร์ที่เชื่อมโยงก่อนที่จะอ้างอิงจากคำพ้อง
Oskar Berggren

จริงฉันคิดว่าฐานข้อมูลอยู่ในสภาพแวดล้อมเซิร์ฟเวอร์เดียวกัน แน่นอนว่าคุณจะต้องเชื่อมโยงฐานข้อมูลอยู่เสมอหากอยู่ห่างไกลกัน ไม่มีวิธีอื่นในการเข้าถึงด้วยความสัมพันธ์ระหว่างฐานข้อมูลกับฐานข้อมูล
Niklas Henricson

0

วัตถุเซิร์ฟเวอร์ ---> เซิร์ฟเวอร์ที่เชื่อมโยง ---> เซิร์ฟเวอร์ที่เชื่อมโยงใหม่

ในเซิร์ฟเวอร์ที่เชื่อมโยงเขียนชื่อเซิร์ฟเวอร์หรือที่อยู่ IP สำหรับเซิร์ฟเวอร์อื่นและเลือก SQL Server ในการรักษาความปลอดภัยเลือก (ทำโดยใช้บริบทความปลอดภัยนี้) เขียนล็อกอินและรหัสผ่านสำหรับเซิร์ฟเวอร์อื่น

เชื่อมต่อแล้วใช้

Select * from [server name or ip addresses ].databasename.dbo.tblname

0

โซลูชันที่ง่ายขึ้นสำหรับการเพิ่มเซิร์ฟเวอร์ที่เชื่อมโยง

เซิร์ฟเวอร์ตัวแรก

EXEC sp_addlinkedserver @server='ip,port\instancename'

เข้าสู่ระบบที่สอง

EXEC sp_addlinkedsrvlogin 'ip,port\instancename', 'false', NULL, 'remote_db_loginname', 'remote_db_pass'

ดำเนินการค้นหาจากเชื่อมโยงกับฐานข้อมูลท้องถิ่น

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.