ActiveDirectoryからローカルアプリケーションデータベースにユーザーを同期する手順を作成しようとしています。私のコードから、次の形式のXMLをストアドプロシージャに渡します。
<AdUsers>
<AdUser AccountSid="S-1-5-21-111111111-111111111-111111111-1111" DisplayName="Test User" EmailAddress="tuser@mail.local" ExchangeServerFk="4" ExchangeServer="https://mail.local" Department="" StatusFK="1" UserName="TUSER">
<AccountSids>
<Sid>S-1-5-21-111111111-111111111-111111111-1111</Sid>
</AccountSids>
</AdUser>
</AdUsers>
次のストアドプロシージャを使用して、XMLとtb_Mailboxesテーブルの行を同期したいと思います。
@adUsers XML, @lastSyncBy VARCHAR (50), @lastSyncOn DATETIME, @defaultProfileId INT, @adDomainId INT
AS
begin try
BEGIN TRANSACTION
--First delete all the mailboxes exist in the database but not in the xml.
delete tb_Mailboxes
where AccountSid not in (
select
rtrim(element.value('text()[1]', 'varchar(100)')) as AccountSid
from
@adUsers.nodes('/AdUsers/AdUser/AccountSids/Sid') t(element)
) AND @adDomainId = AdDomainFk
--Then insert or update existing accounts
MERGE tb_Mailboxes as [target]
USING
(
select
rtrim(element.value('data(@AccountSid)', 'varchar(100)')) as AccountSid
,rtrim(element.value('data(@DisplayName)', 'varchar(100)')) as DisplayName
,rtrim(element.value('data(@EmailAddress)', 'varchar(500)')) as EmailAddress
,rtrim(element.value('data(@ExchangeServerFk)', 'varchar(100)')) as ExchangeServerFk
,rtrim(element.value('data(@ExchangeServer)', 'varchar(150)')) as ExchangeServer
,rtrim(element.value('data(@Department)', 'varchar(100)')) as Department
,rtrim(element.value('data(@StatusFK)', 'varchar(100)')) as StatusFK
,rtrim(element.value('data(@UserName)', 'varchar(100)')) as UserName
,element.query('AccountSids') as SidList
from
@adUsers.nodes('/AdUsers/AdUser') t(element)
) as [source]
on [target].AccountSid IN
(
SELECT rtrim(A.value('text()[1]', 'varchar(100)')) as CurSid
FROM [source].SidList.nodes('Sid') AS FN(A)
)
WHEN MATCHED THEN UPDATE SET
DisplayName = [source].DisplayName
,EmailAddress = [source].EmailAddress
,ExchangeServerFk = [source].ExchangeServerFk
,ExchangeServer = [source].ExchangeServer
,Department = [source].Department
,UserName = [source].UserName
/*,StatusFK = [source].StatusFK*/
,LastSyncOn = @lastSyncOn
,LastSyncBy = @lastSyncBy
WHEN NOT MATCHED THEN INSERT
(
AdDomainFk,
UserName,
DisplayName,
Department,
EmailAddress,
ExchangeServerFk,
ExchangeServer,
AccountSid,
IsAutoDeleteEnabled,
ProfileFk,
Settings,
QueueLastPickedUp,
QueueLastProcessed,
QueueLastFinished,
LastSyncOn,
LastSyncBy,
StatusFK
)
VALUES
(
@adDomainId
,[source].UserName
,[source].DisplayName
,[source].Department
,[source].EmailAddress
,[source].ExchangeServerFk
,[source].ExchangeServer
,[source].AccountSid
,0
,@defaultProfileId
,NULL
,NULL
,NULL
,NULL
,@lastSyncOn
,@lastSyncBy
,[source].StatusFK
);
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
ただし、削除セクションの「NOTIN」と一致セクションの「IN」は機能していないようです。XMLで複数の値を使用するこのタイプのIN句は実現可能ですか?私が見逃しているこの問題へのより良いアプローチはありますか?