SQL Server 가 원 격 데이터 베 이 스 를 실시 간 으로 업데이트 하 는 데 발생 하 는 문제 요약

작업 중 에 이러한 상황 이 발생 하면 테이블 A(서버 서버 서버 A 172.16.8.100 에 있 는 라 이브 러 리 DatabaseA)를 업데이트 하 는 동시에 테이블 B(서버 서버 서버 B 172.16.8.101 에 있 는 라 이브 러 리 DatabaseB)를 업데이트 해 야 한다.
태 블 릿 A 는 태 블 릿 B 와 구조 가 같 지만 데이터 수량 이 꼭 같 지 않 아 태 블 릿 C 도 태 블 릿 B 를 업데이트 할 가능성 이 있 는 것 으로 보인다.데이터 업데이트 가 잦 지 않 아,쉽게 생각 하기 위해 트리거 Tirgger 를 사 용 했 습 니 다.발생 한 몇 가지 문 제 를 기록 하 세 요.
1.타지 데이터베이스 방문
ServerA 에 ServerB 를 가리 키 는 링크 서버 를 만 들 고 계 정 맵 을 만 듭 니 다.addlinkedserver 저장 과정 에서 링크 서버 를 만 듭 니 다.매개 변 수 는 공식 문 서 를 참조 하 십시오.첫 번 째 파라미터 LNKServerA 는 사용자 정의 이름 입 니 다.두 번 째 매개 변수 제품 이름 은 SQL Server 가 제공 하지 않 아 도 됩 니 다.세 번 째 매개 변 수 는 구동 유형 입 니 다.네 번 째 매개 변 수 는 데이터 원본 입 니 다.여기에 SQL Server 서버 주 소 를 쓰 십시오.

exec sp_addlinkedserver 'LNK_ServerB_DatabaseB','','SQLNCLI','172.16.8.101'
링크 서버 를 설정 한 후 기본적으로 같은 로 컬 계 정 을 사용 하여 원 격 데이터 베 이 스 를 로그 인 합 니 다.계 정 이 다 르 면 계 정 맵 이 필요 합 니 다.sp_addlinkedsrvlogin 매개 변 수 는 공식 문 서 를 참조 합 니 다.첫 번 째 매개 변 수 는 위 와 같다.두 번 째 매개 변수 false 는 뒤의 매개 변수 가 제공 하 는 사용자 암 호 를 사용 하여 로그 인 합 니 다.세 번 째 매개 변수 null 은 모든 로 컬 계 정 이 뒤의 사용자 비밀 번 호 를 사용 하여 링크 서버 에 로그 인 할 수 있 도록 합 니 다.세 번 째 매개 변수 가 로 컬 SQL Server 로그 인 사용자 이름 으로 설정 되면 이 사용자 만 원 격 계 정 으로 링크 서버 에 로그 인 할 수 있 습 니 다.마지막 두 개 는 원 격 서버 에 로그 인 한 사용자 와 비밀번호 입 니 다.

exec sp_addlinkedsrvlogin 'LNK_ServerB_DatabaseB','false',null,'user','password'
위 설정 을 삭제 하려 면 다음 과 같 습 니 다.

exec sp_droplinkedsrvlogin 'LNK_ServerB_DatabaseB',null
exec sp_dropserver 'LNK_ServerB_DatabaseB','droplogins'
위의 설정 은 SQL Server Management Studio 관리자 에서 Server Objects 에서 LinkedServers 를 조회 할 수 있 습 니 다.모든 링크 가 정상 이면 링크 서버 의 라 이브 러 리 표를 직접 열 수 있 습 니 다.

주의해 야 할 것 은 상기 두 개의 저장 과정 이 트리거 코드 에 나타 나 지 않 고 서버 ServerA 에서 미리 설정 을 실행 해 야 한 다 는 것 이다.그렇지 않 으 면 트리거 암시 적 업무 에 대한 요구 가 잘못 보 고 될 것 이다."The procedure'sys.spaddlinkedserver' cannot be executed within a transaction.”
2.분산 트 랜 잭 션 설정
SQL Server 의 트리거 는 암시 적 으로 사 무 를 사용 합 니 다.링크 서버 는 원 격 서버 입 니 다.로 컬 서버 와 원 격 서버 사이 에 분포 식 트 랜 잭 션 처 리 를 켜 야 합 니 다.그렇지 않 으 면"The partner transaction manager has disabled its support for remote/network transactions"의 오류 가 발생 합 니 다.저 는 ServerA 와 ServerB 에서 분포 식 트 랜 잭 션 코 디 네 이 터 를 켜 고 분포 식 트 랜 잭 션 을 지원 하기 위해 적당 한 설정 을 했 습 니 다.ServerA 와 ServerB 는 모두 Windows Server 2012 R2 로 다른 버 전 서버 와 유사 하 다.
(1)먼저 Services.msc 에서 Distributed Transaction Coordinator 가 켜 져 있 는 지 확인 합 니 다.다른 버 전의 서버 가 기본 으로 설치 되 어 있 지 않 습 니 다.windows features 를 설치 하 는 방식 으로 이 기능 을 먼저 설치 해 야 합 니 다.

(2)서버 관리 도구 Administrative Tools 에서 Component Services 를 찾 습 니 다.Local DTC 에서 속성 Security 옵션 카드 에 다음 과 같이 설정 되 어 있 습 니 다.관련 보안 설정 을 열 면 서 비 스 를 다시 시작 합 니 다.서버 를 다시 시작 해 야 한 다 는 문서 도 있 지만 2012 R2 는 사용 하지 않 습 니 다.

(3)방화벽 설정,인 바 운 드 와 아웃 바 운 드 모두 열기

3.데이터베이스 필드 text,ntext 처리
업무 중 테이블 A 에 있 는 Content 필드 는 text 형식 으로 테이블 B 에 동기 화 할 때 내용 을 교체 처리 해 야 합 니 다.text 형식 은 유행 이 지난 유형 입 니 다.마이크로소프트 는 공식 적 으로(N)VARCHAR(MAX)로 교체 하 는 것 을 권장 합 니 다.여 기 를 찾 아 볼 수 있 습 니 다.앞으로 디자인 할 때 고려 할 수 있 습 니 다.여기 서 우 리 는 text 를 처리 하 는 것 을 고려 할 수 있 습 니 다.
그러나 트리거 에 서 는 inserted 와 deleted 표 가 text/ntext/image 형식 을 처리 할 수 없습니다.여기에서 저 희 는 곡선 으로 나 라 를 구 하 는 방법 을 사용 하여 데이터베이스 에서 기록 을 임시 표 로 읽 은 다음 에 textptr 와 patindex 함수 와 updatetext 명령 을 통 해 문자열 교체 처 리 를 완성 합 니 다.

if exists(select * from tempdb..sysobjects where id=object_id('tempdb..#temp_tablea')) 
 drop table #temp_tablea
select * into #temp_tablea from TableA where ID = @ID
declare @s varchar(200),@d varchar(200)
select @s='="/_target/',@d='="/_replacement/'
declare @p varbinary(16),@postion int,@l int
select @p=textptr(Content),@l=len(@s),@postion=patindex('%'+@s+'%',Content)+1 from #temp_tablea
while @postion>1
begin
 updatetext #temp_tablea.Content @p @postion @l @d
 select @postion=patindex('%'+@s+'%',Content)+1 from #temp_tablea
end
4.원 격 데이터베이스 작업 수행
링크 서버 를 설정 할 때 원 격 데이터베이스 테이블 에 직접 접근 할 수 있 습 니 다.다음 과 같 습 니 다.

insert into LNK_ServerB_DatabaseB.DatabaseB.dbo.TableB ...
update LNK_ServerB_DatabaseB.DatabaseB.dbo.TableB set ...
그러나 허름 한 SQL 편집 기 는 문법 에 오류 가 발생 할 수 있 습 니 다.또한 프로 그래 밍 을 편리 하 게 하기 위해 exec sp 를 통 해executesql 방식 은 더 많은 유연성 을 얻 을 수 있 습 니 다.사실 exec 는 sql 문 구 를 직접 실행 할 수 있 지만 반환 값 이 있 으 면 비교적 어렵다.원 격 서버 에서 ID 조회 표 TableB 를 통 해 Name,sp 를 되 돌려 줍 니 다.executesql 저장 프로 세 스 는 output 키 워드 를 사용 하여 변 수 를 반환 변수 로 정의 할 수 있 습 니 다.그 중에서@Name output 는 반환 변수 이 고@ID 는 전송 변수 입 니 다.

declare @sql nvarchar(500), @Name nvarchar(50),@ID nvarchar(40)
set @SQL=N'select @Name=Name from LNK_ServerB_DatabaseB.DatabaseB.dbo.TableB where ID=@ID'
exec sp_executesql @SQL,N'@Name nvarchar(50) output,@ID nvarchar(40)',@Name output,@ID
또한 exec 는 sql 문 구 를 직접 실행 합 니 다.본질 적 으로 맞 춤 형 sql 문자열 을 실행 합 니 다.가끔 은 변 수 를 문자열 에 맞 추 는 것 이 어렵 습 니 다.(도대체 몇 개의 작은 따옴표 가 필요 합 니까?)그리고 spexecutesql 은 훨씬 뚜렷 해 졌 다.

declare @SQL nvarchar(500),@Name nvarchar(50),@Count int,@ID nvarchar(40)
set @Name=N'Cat'
set @Count=0
set @ID=N'{00000000-0000-0000-0000-000000000000}'
set @SQL=N'update TableA set Name='''+@Name+''', Count='+@Count+' where ID='''+@ID+''''
exec(@SQL)
set @SQL=N'update TableA set Name=@Name,Count=@Count where ID=@ID'
exec sp_executesql @SQL, N'@Name nvarchar(50),@Count int,@ID nvarchar(40)',@Name,@Count,@ID
위 에서 말 한 것 은 소 편 이 소개 한 SQL Server 가 실시 간 으로 원 격 데이터 베 이 스 를 업데이트 하 는 데 발생 하 는 문제 의 소결 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기