SQL Server에서 서로 다른 두 서버에서 데이터 선택


363

SQL Server의 서로 다른 두 서버에있는 서로 다른 두 데이터베이스에서 동일한 쿼리의 데이터를 어떻게 선택할 수 있습니까?


6
Eric과 Raging Bull의 답변은 매우 편리합니다. 이 기능을 사용하여 DEV에서 PROD로 대량의 데이터를 5 시간에서 18 시간, 17 초로 줄일 수있었습니다.
— Chris Aldrich

@Eric, 약간 모호한 질문을 편집하고 170- 답변으로 만드는 질문 :)
— Eric Wu

답변:


345

찾고있는 것은 연결된 서버입니다. 개체 탐색기 트리의 다음 위치에서 SSMS로 가져올 수 있습니다.

Server Objects-->Linked Servers

또는 sp_addlinkedserver 를 사용할 수 있습니다 .

하나만 설정하면됩니다. 그런 다음 다른 서버에서 다음과 같이 테이블을 호출 할 수 있습니다.

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

소유자가 항상 그런 것은 아니므로 dbo사용하는 스키마로 바꾸십시오.


13
연결된 서버없이 할 수 있습니까?
— 증기

5
@Eric, SSMS에서 서버 개체는 어디에 있습니까?
— Tsahi Asher

9
@TsahiAsher-서버에 연결할 때 서버 개체는 개체 탐색기 트리의 폴더입니다.
— Eric

2
알 수없는 경우 스키마를 생략하여 기본값을 사용할 수도 있습니다. 예를 들어 [OtherServerName].[OtherDB]..[OtherTable]알려진 경우 포함하는 것이 가장 좋습니다.
— Tom Bowers

92

연결된 서버를 사용하여 수행 할 수 있습니다.

일반적으로 연결된 서버는 데이터베이스 엔진이 다른 SQL Server 인스턴스 또는 Oracle과 같은 다른 데이터베이스 제품의 테이블을 포함하는 Transact-SQL 문을 실행할 수 있도록 구성됩니다. Microsoft Access 및 Excel을 포함하여 많은 유형의 OLE DB 데이터 원본을 연결된 서버로 구성 할 수 있습니다.

연결된 서버는 다음과 같은 장점을 제공합니다.

  • 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에 문제가있는 경우 팁입니다. 대화 상자에서 서버를 작성하고 작동하는지 확인한 다음 연결을 마우스 오른쪽 단추로 클릭하고 연결 서버 AS 작성
— Richard Housham

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

연결된 서버 사용을 볼 수도 있습니다. 링크 된 서버는 DB2 플랫폼과 같은 다른 유형의 데이터 소스 일 수도 있습니다. 이것은 SQL Server TSQL 또는 Sproc 호출에서 DB2에 액세스하는 방법 중 하나입니다 ...


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에는 바이올린 기능이있는 형식 파일이 필요하지 않을 수도있는 BULK 기능이 있습니다.
  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 테이블 쿼리에이 방법을 사용합니다.
— Paul

실제로 정말 멋진 기능입니다. 단점은 쿼리를 두 번 실행하고 동시에 병합하기 때문에 결과 집합의 스키마가 일치해야한다는 것입니다. 결과 세트에 참여할 수없고 세트를 별도로 평가하도록 구성해야하더라도 링크 된 서버에서와 같이 SQL 자체 내의 서버를 참조 할 수 있으면 좋을 것입니다.
— Kross

1
@Kross 당신은 일종의 할 수 있습니다. #output 테이블을 작성하고 @@ SERVERNAME을 기반으로 논리를 수행 한 후 #output에 데이터를 채운 다음 선택하여 종료하십시오. 나는 정보의 수준 / 열이 다른 SQL2000과 SQL2008R2 머신에서 로그 정보를 쿼리하는 것과 비슷한 일을했지만 @@ SERVERNAME 대신 서버 버전 변수를 사용하고있었습니다.
— Paul

9

SQL_server 2008을 원격 서버에서 호스팅되는 SQL_server 2016에 연결하는 것과 동일한 문제가있었습니다. 다른 답변은 저에게 직접 효과가 없었습니다. 다른 사람에게 유용 할 수 있다고 생각하면서 여기에 조정 된 솔루션을 작성합니다.

원격 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.dddSQLserver DB를 호스팅하는 원격 서버의 IP 주소입니다.

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]

다른 사람들이 지적했듯이, 작동하지 않으면 서버가 연결되어 있지 않기 때문입니다.

오류가 발생합니다.

sys.servers에서 서버 DB2를 찾을 수 없습니다. 올바른 서버 이름이 지정되었는지 확인하십시오. 필요한 경우 저장 프로 시저 sp_addlinkedserver를 실행하여 sys.servers에 서버를 추가하십시오.

서버를 추가하려면

참조 : sp_addlinkedserver를 사용하여 서버를 추가하려면 링크 : [1] : sp_addlinkedserver를 사용하여 서버를 추가하려면

sys.servers에 무엇이 있는지 보려면 그냥 쿼리하십시오.

SELECT * FROM [sys].[servers]


2

@ Super9는 데이터 공급자 SQLOLEDB 와 함께 SQL Server 인증을 사용하여 OPENDATASOURCE에 대해 설명했습니다 . 방금 한 테이블의 코드 스 니펫이 코드가 실행중인 현재 서버 데이터베이스에 있고 다른 서버 '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 내에서 실행되고 서버 A에 존재하지 않는 데이터베이스 서버 B에서 테이블을 찾습니다. 서버 B에서 테이블을 호출하는 A 데이터베이스에서 동의어를 추가하십시오. 스키마 또는 다른 데이터베이스 이름을 포함하려면 평소마다 테이블 이름을 호출하면 작동합니다.

동의어가 일종의 연결이기 때문에 서버를 연결할 필요가 없습니다.


1
그렇다면이 문맥에서 "동의어"란 무엇입니까?
— Oskar Berggren

다른 데이터베이스의 기본 개체를 참조하는 데이터베이스 개체입니다. 여기에 더 많은 정보 : docs.microsoft.com/en-us/sql/relational-databases/synonyms/...
— 니클라스 Henricson

쿨, 나는 그 기능에 대해 몰랐다. 그러나 그들은 또한 연결된 서버가 필요하지 않다고 말하지만 방법을 알지 못합니다. 동의어 자체는 단지 동의어 인 것으로 보이며 특정 원격 기능을 포함하지 않습니다. docs.microsoft.com/en-us/sql/t-sql/statements/…의 예제 B에서는 동의어에서 참조하기 전에 연결된 서버를 만듭니다.
— 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'

로컬 DB에 연결된 쿼리 실행

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.