2016-09-26 3 views
1

SQL CLR 트리거를 사용하여 관계형 DB에서 MongoDB 인스턴스로 업데이트를 푸시합니다. 두 데이터베이스 모두 동일한 Windows 2012 컴퓨터에서 실행됩니다.SQL Server 2008 CLR 트리거에서 MongoDB에 액세스

내 SQL CLR 프로젝트는 .NET 3.5를 기반으로하며 mongocsharpdriver 1.10.0을 사용하고 있습니다.

SqlPipe pipe = SqlContext.Pipe; 
pipe.Send("Begin ReportUpdateTrigger.VTProperty"); 

try 
{ 
    var settings = new MongoClientSettings(); 
    settings.Server = new MongoServerAddress("127.0.0.1", 27017); 

    var client = new MongoClient(settings); 
    var server = client.GetServer(); 

    var db = server.GetDatabase("VTProperty"); 
    var coll = db.GetCollection<object>("Property"); 

    var item = new { name = "test", datecreated = DateTime.Now }; 
    coll.Insert(item); 
} 
catch (Exception ex) 
{ 
    pipe.Send("Error sending update to Reporting database: " + ex.Message); 
} 

pipe.Send("Done ReportUpdateTrigger.VTProperty"); 

(이 그냥 MongoDB의 작업이 작동하는지 확인하기 위해 테스트 코드) : 다음과 같이 내 트리거 내에서

C# 코드입니다.

별도의 콘솔 앱에서 똑같은 코드를 실행하고 아무런 문제없이 데이터가 Mongo에 게시됩니다.

Begin ReportUpdateTrigger.VTProperty Error sending update to Reporting database: Unable to connect to server 127.0.0.1:27017: The type initializer for 'MongoDB.Bson.Serialization.BsonSerializer' threw an exception.. Done ReportUpdateTrigger.VTProperty

내 DLL (과 MongoDB를 드라이버를 포함하여 모든 지원 DLL을) 가지고있는 DB 서버 내에서 어셈블리로 참조 :

트리거에서 실행, 나는 다음과 같은 오류를 참조하십시오. CLR이 사용됩니다. SQL 출력 창에서 사용자 정의 상태 및 오류 메시지를 받기 때문에 트리거가 실행 중임을 압니다.

내 직감은 트리거 코드를 실행하는 사용자/프로세스가 Mongo 인스턴스에 액세스 할 수 없다는 점입니다. 따라서 "서버 127.0.0.1:27017에 연결할 수 없습니다"오류가 발생합니다. 내 다음 단계가 무엇인지 확신 할 수 없습니다. 기본적으로

답변

0

는 SQLCLR 외부 액세스는 MSSQLSERVER 서비스 (또는 MSSQL $ 인스턴스 이름, 또는 같은)의 (계정 "으로 로그온"즉) 서비스 계정의 보안 컨텍스트를 가지고있다. 기본적으로 해당 서비스 계정은 로컬 시스템 계정입니다. 여기서 두 가지 중 하나를 수행 할 수 있습니다 : 당신의 MSSQLSERVER 서비스가 계정으로 "로컬 시스템"을 사용

  1. 경우, 실제 로컬 또는 도메인/AD 계정을 만들고 서비스 계정을 확인하십시오. 그런 다음 새로운 실제 계정이 MongoDB에 액세스 할 수 있는지 확인하십시오.

    무엇이든 관계없이 SQL Server와 같은 서비스에 자체 서비스 계정을 사용하는 것이 가장 좋습니다. 따라서 퍼밋을 쉽게 제어하고 제한 할 수 있습니다.

  2. Windows 로그인을 사용하는 경우 .NET 코드에서 가장을 사용하도록 설정할 수 있습니다. 가장 (impersonation)을 사용할 때 외부 호출의 보안 컨텍스트는 SQLCLR 개체를 실행중인 Windows 로그인으로 설정됩니다.

    이를 위해, 당신은 당신의 코드를 다음과 같이 뭔가를 추가해야합니다 :

    using System.Security.Principal; 
    
    // above the "try" block 
    WindowsImpersonationContext _ImpersonationIdentity = null; 
    
    // inside the "try", before anything else 
    _ImpersonationIdentity = SqlContext.WindowsIdentity.Impersonate(); 
    
    // in a "finally" block 
    if (_ImpersonationIdentity != null) 
    { 
        _ImpersonationIdentity.Undo(); 
    } 
    
+0

나는 SQL Server 서비스에서 실행하는 사용자를 변경했습니다. 이것은 로컬 사용자이고 Administrators 그룹의 구성원입니다 (초기 테스트 용). SSCM을 사용하여 사용자 계정을 변경하고 서비스가 중지되었거나 다시 시작되어 변경 사항이 적용되었음을 확인했습니다. SQL 사용자가 로컬 관리자 인 경우 mongo 인스턴스에 액세스하지 못하게 할 수있는 다른 방법은 무엇입니까? –

+0

@KyleSullens 그래서 서비스 계정을 변경했지만 여전히 가장을 사용하지 않았습니다. 맞습니까? 가장 (Impersonation)도 구현 한 경우 서비스 계정은 중요하지 않으며 SQL Server 내에서 SQLCLR 개체를 실행하는 로그인 만 중요합니다.가장을 사용하지 않는다면이 로컬 사용자와 MongoDB에 연결하여 작동하는지 확인하십시오. 또한 오류 메시지를 다시 읽었는데 형식 이니셜 라이저에서 오는 것입니까? 어떤 경우에는 가장을 사용할 수 없습니다. 형식 이니셜 라이저 코드가 무엇을하는지 궁금합니다. 연결 오류를 나타내는 MongoDB 오류 로그가 있습니까? –