Truy vấn mẫu máy chủ liên kết SQL Server


93

Khi ở trong Management Studio, tôi đang cố gắng chạy truy vấn / thực hiện kết hợp giữa hai máy chủ được liên kết. Đây có phải là cú pháp đúng khi sử dụng các máy chủ db được liên kết không:

select foo.id 
from databaseserver1.db1.table1 foo, 
     databaseserver2.db1.table1 bar 
where foo.name=bar.name

Về cơ bản, bạn có đặt tên máy chủ db vào db.table không?

Câu trả lời:


186

Định dạng có lẽ phải là:

<server>.<database>.<schema>.<table>

Ví dụ: DatabaseServer1.db1.dbo.table1


Cập nhật : Tôi biết đây là một câu hỏi cũ và câu trả lời tôi có là đúng; tuy nhiên, tôi nghĩ rằng bất kỳ ai khác tình cờ gặp phải điều này nên biết một vài điều.

Cụ thể, khi truy vấn máy chủ được liên kết trong tình huống tham gia, bảng TOÀN BỘ từ máy chủ được liên kết có thể sẽ được tải xuống máy chủ mà truy vấn đang thực thi từ đó để thực hiện thao tác kết hợp. Trong trường hợp của OP, cả table1từ DB1table1từ DB2sẽ được chuyển toàn bộ đến máy chủ thực hiện truy vấn, có lẽ được đặt tên DB3.

Nếu bạn có các bảng lớn, điều này có thể dẫn đến một hoạt động mất nhiều thời gian để thực thi. Xét cho cùng, giờ đây nó bị hạn chế bởi tốc độ lưu lượng mạng, chậm hơn tốc độ truyền của bộ nhớ hoặc thậm chí là tốc độ đĩa.

Nếu có thể, hãy thực hiện một truy vấn duy nhất đối với máy chủ từ xa, không tham gia vào bảng cục bộ, để kéo dữ liệu bạn cần vào bảng tạm thời. Sau đó, truy vấn ra khỏi đó.

Nếu điều đó là không thể thì bạn cần phải xem xét những thứ khác nhau có thể khiến máy chủ SQL phải tải toàn bộ bảng cục bộ. Ví dụ: sử dụng GETDATE()hoặc thậm chí một số phép nối nhất định. Những kẻ giết hiệu suất khác bao gồm không đưa ra các quyền thích hợp.

Xem http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ để biết thêm thông tin.


11
nếu tên databaseserver có một gạch nối, cần phải bao quanh nó với dấu ngoặc vuông
bmw0128

4
@ bmw0128: Tốt hơn hết, hãy sử dụng dấu ngoặc kép: nó được hỗ trợ bởi hầu hết mọi nền tảng, không giống như dấu ngoặc vuông của Microsoft.

2
Bạn cũng cần sử dụng dấu ngoặc vuông hoặc dấu ngoặc kép khi tên máy chủ cơ sở dữ liệu có dấu chấm trong đó.
David Brunow

4
Nếu bạn không chắc chắn về bất kỳ định tính nào, hãy xem chi tiết bảng trong Máy chủ được liên kết trong Trình khám phá đối tượng SSMS, nhấp chuột phải và Bảng tập lệnh dưới dạng, CHỌN Tới và Cửa sổ trình soạn thảo truy vấn mới. Câu lệnh SELECT kết quả sẽ bao gồm đường dẫn chính xác, đủ điều kiện đến bảng. Tôi đã có một vòng loại cơ sở dữ liệu bí ẩn khi làm việc với Sybase và điều này đã cho tôi tên chính xác.
John Mo

Tôi nghĩ rằng bạn không chính xác khi nói rằng toàn bộ bảng sẽ được chuyển. Bạn có thể cung cấp một số thông tin tham khảo về nơi bạn lấy thông tin đó không? Tôi vừa thử kết hợp với một bảng có 204 triệu hàng (dữ liệu 16GB, chỉ mục 6,6 GB) trên máy chủ được liên kết và mất 47 mili giây để liên kết đến 5 hàng, 7 mili giây đối với truy vấn thứ hai vì dữ liệu có lẽ đã được lưu vào bộ nhớ đệm. Có thể nếu tham gia của bạn yêu cầu quét bảng trên bảng được liên kết, nó sẽ phải chuyển tất cả?
Jason Goemaat

32
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')

Điều này có thể giúp bạn.


Đã ủng hộ. Điều này hoạt động khi bạn đang liên kết MySQL với MS SQL.
Baz Guvenkaya

3
Nói cách khác, điều này đang tạo ra một truy vấn chuyển qua. Hãy nhớ rằng câu lệnh truy vấn phải được viết bằng SQL gốc cho máy chủ. Cú pháp cho Oracle là khác với Teradata khác với SQL Server, vv
AxGryndr

10

Nếu bạn vẫn thấy vấn đề với <server>.<database>.<schema>.<table>

Bao gồm tên máy chủ trong []


Cẩn thận: Tôi thực hiện một tạo bảng từ chọn sử dụng [], và thay vì được tạo ra trên máy chủ liên kết, bảng đã được tạo ra tại địa phương với một cái tên nhưdbo.databaseserver1.db1.dbo.table1
biscuit314

9

Đối với những người gặp khó khăn với những câu trả lời khác này , hãy thửOPENQUERY

Thí dụ:

 SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]') 

Hoạt động cho SQL Server
Tom Stickel

8

Bạn cần chỉ định lược đồ / chủ sở hữu (dbo theo mặc định) như một phần của tham chiếu. Ngoài ra, bạn nên sử dụng kiểu nối mới hơn (ANSI-92).

select foo.id 
    from databaseserver1.db1.dbo.table1 foo
        inner join databaseserver2.db1.dbo.table1 bar 
            on foo.name = bar.name

cú pháp nối bên trong thích hợp hơn so với các phép nối ngầm?
bmw0128

2
@ bmw0128: Vâng, vì một số lý do. IMHO, điều quan trọng nhất là việc bạn vô tình ghi kết hợp sản phẩm chéo quá dễ dàng khi bạn có bảng của mình và tham gia ở hai nơi khác nhau.

Lưu ý rằng phần 4 chấm KHÔNG hoạt động đối với một số máy chủ được liên kết không phải SQL-Server. Nó có thể gây ra lỗi như ... Một lược đồ hoặc danh mục không hợp lệ đã được chỉ định cho nhà cung cấp "MSDASQL" cho máy chủ được liên kết "MyLinkedServer".
brewmanz

6
select * from [Server].[database].[schema].[tablename] 

Đây là cách gọi chính xác. Đảm bảo xác minh rằng các máy chủ được liên kết trước khi thực hiện truy vấn!

Để kiểm tra các máy chủ được liên kết, hãy gọi:

EXEC sys.sp_linkedservers 

Điều này KHÔNG hoạt động đối với một số máy chủ được liên kết không phải SQL-Server. Nó làm phát sinh lỗi như ... Một lược đồ hoặc danh mục không hợp lệ đã được chỉ định cho nhà cung cấp "MSDASQL" cho máy chủ được liên kết "MyLinkedServer".
brewmanz

4
select name from drsql01.test.dbo.employee
  • drslq01 là servernmae - người tìm kiếm được liên kết
  • kiểm tra là tên cơ sở dữ liệu
  • dbo là giản đồ - lược đồ mặc định
  • nhân viên là tên bảng

Tôi hy vọng nó sẽ giúp hiểu, cách thực thi truy vấn cho máy chủ được liên kết


2

Thông thường không nên sử dụng truy vấn trực tiếp trong trường hợp máy chủ được liên kết vì nó sử dụng nhiều cơ sở dữ liệu tạm thời của máy chủ SQL. Ở bước đầu tiên, dữ liệu được truy xuất vào DB tạm thời sau đó quá trình lọc xảy ra. Có rất nhiều chủ đề về điều này. Tốt hơn là sử dụng OPENQUERY mở vì nó chuyển SQL đến máy chủ được liên kết nguồn và sau đó nó trả về kết quả đã lọc, ví dụ:

SELECT *
FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')

Câu trả lời này không bao gồm một tên cơ sở dữ liệu
Chris Nevill

2
Tôi đã cung cấp thông tin cơ sở dữ liệu trong khi tạo máy chủ được liên kết. Để biết chi tiết, bạn có thể xem liên kết MSDN bên dưới: msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
Muhammad Yaseen.

Tôi có thể làm gì nếu máy chủ được liên kết của tôi yêu cầu xác thực và tôi chỉ đang cố gắng truy vấn từ ứng dụng PHP của mình bằng PDO?
nekiala

Bạn sẽ thực hiện phép nối từ cơ sở dữ liệu 1 đến cơ sở dữ liệu trên máy chủ được liên kết như thế nào bằng cách sử dụng phương pháp này?
Eaglei22

2

Đối với những gì nó đáng giá, tôi thấy cú pháp sau hoạt động tốt nhất:

CHỌN * TỪ [LINKED_SERVER] ... [BẢNG]

Tôi không thể làm cho các đề xuất của người khác hoạt động bằng cách sử dụng tên cơ sở dữ liệu. Ngoài ra, nguồn dữ liệu này không có lược đồ.


2

nhấp chuột phải vào bảng và nhấp vào bảng tập lệnh khi chọn

nhập mô tả hình ảnh ở đây


Đó không phải là những gì OP hỏi
Fandango68

2
điều này cho thấy cách lấy cú pháp chính xác cho truy vấn chọn trên bảng được liên kết. kết quả là như của seans câu trả lời
Shimon Doodkin

1
@ShimonDoodkin, một ví dụ tuyệt vời của không cho tôi một con cá, nhưng dạy tôi làm thế nào để cá
Amro

0

Làm theo Truy vấn là hoạt động tốt nhất.

Hãy thử Truy vấn này:

SELECT * FROM OPENQUERY([LINKED_SERVER_NAME], 'SELECT * FROM [DATABASE_NAME].[SCHEMA].[TABLE_NAME]')

Nó rất hữu ích để liên kết MySQL với MS SQL


0

PostgreSQL :

  1. Bạn phải cung cấp tên cơ sở dữ liệu trong DSN Nguồn dữ liệu .
  2. Chạy Management Studio với tư cách là Quản trị viên
  3. Bạn phải bỏ qua DBName khỏi truy vấn :

    SELECT * FROM OPENQUERY([LinkedServer], 'select * from schema."tablename"')

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.