我正在尝试编写一个将用户从 Active Directory 同步到我的本地应用程序数据库的过程。从我的代码中,我将以下格式的 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
但是,删除部分中的“NOT IN”和匹配部分中的“IN”似乎不起作用。这种在 XML 中使用多个值的 IN 子句是否可行?有没有更好的方法来解决我缺少的这个问题?