【问题标题】:How to compare varbinary data type in where clause如何比较where子句中的varbinary数据类型
【发布时间】:2017-10-09 12:17:03
【问题描述】:

我有一个链接服务器,它被创建用于从一个特定的组织单元中提取用户详细信息,并带有一个预定的 sql 作业代理。

创建该表以保存用户详细信息,其中有一列 ObjectGUID 编号,类型定义为 varbinary(50)(我不知道为什么..)。

该过程通过比较保存的用户表中的 ObjectGUID 编号来检查是否有新用户,如果有新编号,则将新用户插入表中。

但是我注意到比较实际上并不能正常工作。

SELECT 
tbl.objectGUID AS UserGUID 
FROM [dbo].[ActiveDirectoryUsers] tbl
WHERE tbl.objectGUID NOT IN (SELECT UserGUID FROM dbo.Users)

当我创建一个新用户时,新用户出现在 ActiveDirectoryUsers 视图中。

但是当添加 where 子句以将结果与用户表进行比较时,结果始终为空。看起来我需要将 varbinary 转换或转换为 varchar 然后进行比较。我尝试将 varbinary 转换为 varchar 和 uniqueidentifier,但它仍然不起作用。

知道如何进行比较吗?

更新

CREATE VIEW [dbo].[ActiveDirectoryUsers] AS 
SELECT "SAMAccountName" AS sAMAccountName, "mail" AS Email,
  "objectGUID" AS objectGUID
   FROM OpenQuery(ADSI, 'SELECT SAMAccountName, mail, objectGUID
               FROM   ''ldapconnectionstring.com''')

Users 表中的 objectGUID 示例

0x1DBCC071C69C8242B4895D42750969B1

【问题讨论】:

  • 请使用字段及其类型更新您的问题。什么是 varbinary(50)、dbo.Users.UserGUID?还是 [dbo].[ActiveDirectoryUsers].objectGUID?两个都奇怪?
  • 如果dbo.ActiveDirectoryUsers.objectGUIDvarbinary(50),那么dbo.Users.UserGUID 也是吗?还是 GUID 的字符串表示形式?
  • ActiveDirectoryUsers.objectGUID 未定义。这是一个视图。我添加了视图创建脚本。但是当我查看 Sql management studio 中列下的视图时,我可以看到 objectGUID 的类型是 varbinary(4000)。
  • 所以一个字段 id varbinary(50) 和另一个 varbinary(4000)? varchar 在哪里?
  • @sepupic 没有 varchar。我只是问如何让查询工作。当我在 varbinary 之间进行比较时,结果是错误的。即使 objectGuid 不在 Users 表中,结果也不会显示该用户。

标签: sql-server active-directory


【解决方案1】:

您不应该将varbinary 转换为特定的,以便能够在WHERE 子句中使用它。 您的问题是您使用 NOT IN 存在 NULL 值。

尝试先按原样执行我的代码(它将返回 1 行),然后取消注释 NULL 值插入并再次执行它。 这次你会得到 0 行:

 declare @t1 table (guid varbinary(50))
 insert into @t1
 values(0x1DBCC071C69C8242B4895D42750969B1)--, (null);

 declare @t2 table (guid varbinary(50))
 insert into @t2
 values(0x1DBCC071C69C8242B4895D42750969B1), (0x1DBCC071C69C8242B4895D42750969B2);

 select *
 from @t2 t2
 where t2.guid not in (select guid from @t1);

要解决您的问题,请尝试使用NOT EXISTS 而不是NOT IN,如下所示:

 select *
 from @t2 t2
 where not exists (select * 
                   from @t1 t1
                   where t1.guid = t2.guid);

在你的情况下,代码应该是这样的:

SELECT tbl.objectGUID AS UserGUID 
FROM [dbo].[ActiveDirectoryUsers] tbl
WHERE not exists (SELECT * 
                  FROM dbo.Users u
                  where u.UserGUID = tbl.objectGUID );

【讨论】:

  • 检查 null 解决了这个问题。检查 null 或使用您的解决方案不存在之间有什么区别吗?
  • 也许在很久以前存在差异,但现在服务器足够智能,可以为两种情况生成相同的执行计划,因此它完全知道它需要什么。也许 NOT EXISTS 在某种意义上更直观,它对应于你想要的英文描述
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
相关资源
最近更新 更多