성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>SQL 서버 - DB 테이블의 데이터 변경에 대한 알림 처리</h1> <p> 마침, 아래와 같이 질문해 주신 분이 있군요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 주식형태의 프로그램 처럼 SQL서버의 특정 필드 데이터의 변화가 있을때 재 클라이언트가 정보를 갱신 할 수 있게 하는 방법은 없을까요? ; <a target='tab' href='http://www.sysnet.pe.kr/3/0/981'>http://www.sysnet.pe.kr/3/0/981</a> </pre> <br /> 덕분에, Notification Services가 2008부터 누락되었다는 것도 알게 되었습니다. 아래의 글에 따르면, 누락은 되었지만 SQL Server 2005 SP3에 포함된 Notification Services와 연동이 되는 것은 가능하다고 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > SQL Server Notification Services ; <a target='tab' href='http://en.wikipedia.org/wiki/SQL_Server_Notification_Services'>http://en.wikipedia.org/wiki/SQL_Server_Notification_Services</a> </pre> <br /> 어찌되었든, 저도 Notification Services를 사용해 본 적은 없으므로 더 이상 언급할 만한 가치는 없겠고.<br /> <br /> 이제 다른 방법을 찾아봐야 하는데, 다행히 검색을 해보면 WMI 이벤트로 알림 기능이 제공된다는 글이 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > wmi Sql table notification ; <a target='tab' href='http://www.ureader.com/msg/14861679.aspx'>http://www.ureader.com/msg/14861679.aspx</a> </pre> <br /> 아하, AUDIT_SCHEMA_OBJECT_ACCESS_EVENT가 있다는군요. 사용 방법에 관한 구체적인 코드는 다음과 같이 하면 되겠습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Sample: Using the WMI Event Provider with the .NET Framework ; <a target='tab' href='https://docs.microsoft.com/en-us/sql/relational-databases/wmi-provider-server-events/sample-using-the-wmi-event-provider-with-the-net-framework'>https://docs.microsoft.com/en-us/sql/relational-databases/wmi-provider-server-events/sample-using-the-wmi-event-provider-with-the-net-framework</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> 실제로 한번 테스트를 해보았습니다. 우선, 다음과 같이 간단한 DB 및 테이블을 만들고,<br /> <br /> <img alt='sql_wmi_event_1.png' src='/SysWebRes/bbs/sql_wmi_event_1.png' /><br /> <br /> 이를 기반으로 WMI Query를 구성하는데, DB 이름으로 'TestDB' 및 테이블 이름으로 'TestTable'로 제한하고 수행되는 쿼리에 "INSERT INTO", "UPDATE" 문자열을 담고 있으면 알림을 받도록 했습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string query = @"Select * From <span style='color: blue; font-weight: bold'>AUDIT_SCHEMA_OBJECT_ACCESS_EVENT</span> Where <span style='color: blue; font-weight: bold'>ObjectName = 'TestTable' And DatabaseName = 'TestDB'</span> and (<span style='color: blue; font-weight: bold'>TextData Like '%INSERT INTO%' or TextData Like '%UPDATE %'</span>)"; // Default namespace for default instance of SQL Server string managementPath = @"\\.\root\Microsoft\SqlServer\ServerEvents\<span style='color: blue; font-weight: bold'>MSSQLSERVER</span>"; ManagementEventWatcher watcher = new ManagementEventWatcher(new WqlEventQuery(query)); ManagementScope scope = new ManagementScope(managementPath); scope.Connect(); watcher.Scope = scope; Console.WriteLine("Watching..."); while (true) { ManagementBaseObject obj = <span style='color: blue; font-weight: bold'>watcher.WaitForNextEvent();</span> foreach (PropertyData data in obj.Properties) { Console.Write("{0}:", data.Name); if (data.Value == null) { Console.WriteLine("<null>"); } else { Console.WriteLine(data.Value.ToString()); } } } </pre> <br /> 아쉽게도, 위의 WMI 코드를 실행하려면 '관리자 권한'이 필요하다는 정도겠군요. 동작이 잘 되는지 아래와 같이 INSERT 쿼리를 실행해 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > INSER INTO TestTable(id) VALUES(1) </pre> <br /> 이벤트를 받게 되고, PropertyData 내용은 다음과 같이 출력됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ApplicationName:Microsoft SQL Server Management Studio - Query BinaryData:System.Byte[] ClientProcessID:12312 ColumnPermissions:0 ComputerName:TESTPC DatabaseID:7 <span style='color: blue; font-weight: bold'>DatabaseName:TestDB</span> DBUserName:dbo EventSequence:744 EventSubClass:0 HostName:TESTPC IsSystem:0 LineNumber:1 LoginName:TESTPC\TestUser LoginSid:System.Byte[] NestLevel:0 NTDomainName:TESTPC NTUserName:TestUser <span style='color: blue; font-weight: bold'>ObjectName:TestTable</span> ObjectType:8277 OwnerName:dbo ParentName:dbo Permissions:8 PostTime:20110711175034.000470+000 RequestID:0 SECURITY_DESCRIPTOR:<null> ServerName:TESTPC SessionLoginName:TESTPC\TestUser SPID:53 SQLInstance:MSSQLSERVER StartTime:20110711175034.000470+000 Success:1 <span style='color: blue; font-weight: bold'>TextData:INSERT INTO [TestTable]([Id]) values(@1)</span> TIME_CREATED:129548478344755975 TransactionID:95564 XactSequence:227633266689 </pre> <br /> UPDATE의 경우에도,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > UPDATE TestTable SET Id = 4 </pre> <br /> 알림으로 받게되는 속성은 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ApplicationName:Microsoft SQL Server Management Studio BinaryData:System.Byte[] ClientProcessID:12312 ColumnPermissions:1 ComputerName:TESTPC DatabaseID:7 <span style='color: blue; font-weight: bold'>DatabaseName:TestDB</span> DBUserName:dbo EventSequence:1180 EventSubClass:0 HostName:TESTPC IsSystem:0 LineNumber:1 LoginName:TESTPC\TestUser LoginSid:System.Byte[] NestLevel:0 NTDomainName:TESTPC NTUserName:TestUser <span style='color: blue; font-weight: bold'>ObjectName:TestTable</span> ObjectType:8277 OwnerName:dbo ParentName:dbo Permissions:2 PostTime:20110711175410.000623+000 RequestID:0 SECURITY_DESCRIPTOR:<null> ServerName:TESTPC SessionLoginName:TESTPC\TestUser SPID:58 SQLInstance:MSSQLSERVER StartTime:20110711175410.000623+000 Success:1 <span style='color: blue; font-weight: bold'>TextData:UPDATE [TestTable] set [Id] = @1</span> TIME_CREATED:129548480515150114 TransactionID:98062 XactSequence:249108103169 </pre> <br /> 아... 아깝군요. 실행 시간 정보까지만 나왔어도 <a target='tab' href='/2/0?wtype=33'>제니퍼 닷넷</a>에 기능 추가를 해보는 것도 좋을 텐데. ^^<br /> <br /> <a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=609&boardid=331301885'>첨부된 파일은 위의 코드를 포함한 예제 프로젝트</a>입니다.<br /> </p><br /> <br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1833
(왼쪽의 숫자를 입력해야 합니다.)