Sql server 在SQL Server中存储和检索Active Directory对象GUID

Sql server 在SQL Server中存储和检索Active Directory对象GUID,sql-server,active-directory,Sql Server,Active Directory,我很快就能做到这一点。我需要在我们的内部网上识别一个用户。我需要将该用户的objectGUID存储在SQL Server数据库表中,并能够再次检索该记录。我有几个不同的应用程序,PHP、ASP Classic和ASP.Net。我认为在SQLServer中执行广告查找可能是最简单的 我可以使用本教程中的步骤连接到AD 我可以检索objectGUID和我需要的任何其他内容,但我不确定如何在数据库中存储objectGUID,或者如何使用objectGUID查询数据库 我认为它是数据类型128长度字节数

我很快就能做到这一点。我需要在我们的内部网上识别一个用户。我需要将该用户的objectGUID存储在SQL Server数据库表中,并能够再次检索该记录。我有几个不同的应用程序,PHP、ASP Classic和ASP.Net。我认为在SQLServer中执行广告查找可能是最简单的

我可以使用本教程中的步骤连接到AD

我可以检索objectGUID和我需要的任何其他内容,但我不确定如何在数据库中存储objectGUID,或者如何使用objectGUID查询数据库

我认为它是数据类型128长度字节数组?需要转换,但我不知道如何转换

从active directory中选择一条记录并插入到表中,会将插入的objectGUID数据类型显示为varbinary256

select  *
into temp_table
from  openquery(adsi, '
select  givenName,
                sn,
                sAMAccountName,
                objectGUID              
from    ''LDAP://dc=somedomain,dc=com''
where   sAMAccountName = ''some_user''
')
为了测试,我尝试使用从上面的temp_表检索到的objectGUID查询AD

declare @qry varchar(8000)
declare @var varbinary(256)
set @var = (SELECT objectGUID from temp_table)
set @qry = 'select *
from openquery(ADSI, ''
    select
    givenName, 
    sn, 
    sAMAccountName
    from ''''LDAP://DC=somedomain,DC=com'''' 
    where objectGUID = ''''+@var+''''   
    ORDER BY displayName
'')'

exec(@qry)
不返回任何行

起初,我认为这是正确的语法和引号

where objectGUID = '+@var+'
但返回错误:数据类型的运算符无效。运算符等于add,类型等于varchar

所以,也许我的语法错误,或者仍然是一个数据类型问题


提前感谢。

您是否尝试过在TSQL中强制转换或转换?有几个例子

不清楚如何使用objectGUID查询数据库是什么意思,但如果您想知道确切的数据类型,有两种方法:

如果您至少使用SQL Server 2012,则可以尝试。它有几个限制,因此并不适用于所有情况

您可以将结果转储到临时表,然后检查其结构:

SELECT fields
INTO #tmp
FROM openquery(...);

EXEC tempdb.dbo.sp_help '#tmp';
创建列以存储值或声明局部变量时,使用返回的任何数据类型,可能是BINARY128或VARBINARY128

编辑: 所以我们现在知道objectGUID是一个VARBINARY256。为了在查询中正确使用它,请从已转义字符串中的转义字符串中删除三组单引号。此外,我们还需要将VARBINARY转换为VARCHAR,以便将其连接到动态SQL字符串中。使用转换功能时,确保使用样式编号1,将十六进制数字转换为十六进制数字串,即0x12D5;如果不指定样式,默认操作是将这些十六进制数字表示的字符转换为Hello

DECLARE @Query VARCHAR(8000),
        @ObjectGUID VARBINARY(256);

SELECT @ObjectGUID = objectGUID
FROM   temp_table;

SET @Query = 'SELECT *
FROM OPENQUERY(ADSI, ''
    SELECT
    givenName, 
    sn, 
    sAMAccountName
    FROM ''''LDAP://DC=somedomain,DC=com'''' 
    WHERE objectGUID = ' + CONVERT(VARCHAR(300), @ObjectGUID, 1) + '
    ORDER BY displayName;
 '')';

PRINT @Query; -- see what SQL is being executed
EXEC(@Query);

我还将AD中的objectGUID存储到项目中的SQL server中,并使用uniqueidentifier。但是,我不使用OpenQuery,而是使用windows服务不断地从AD同步并填充数据库

虽然从AD对象获取时,GUID显示为二进制数组varbinary, 它实际上表示一个GUID,SQL中对应的类型是uniqueidentifier。 GUID为16字节,大小仅为128位

这没有经过测试,但请尝试以下方法:

Select CONVERT(uniqueIdentifier,objectGUID) as Id, ...
FROM OpenQuery(ADSI,
    'SELECT objectGUID, ...
     FROM ...
     WHERE...')

我无法在where子句中使用objectGUID,但我发现我可以直接绑定到objectGUID,从而得到相同的最终结果

DECLARE @qry varchar(8000) 
DECLARE @ObjectGUID uniqueIdentifier

SET @ObjectGUID = (SELECT objectGUID FROM temp_table)

SET @qry = 'select *
FROM openquery(ADSI, ''
    SELECT  givenName,
                sn,
                sAMAccountName,
                objectGUID              
from    ''''LDAP://<GUID=' + CAST(@ObjectGUID as CHAR(36)) + '>''''
'')'

EXEC(@qry)

要在单个查询中从AD检索数据,当您请求特定的对象GUID或多个GUID时,有一种方法可以使用where子句,而不是从LDAP://表达式中检索数据,这在查询单个GUID时非常方便

查询where子句中Active Directory对象的GUID必须具有字符串形式,其中GUID以十六进制表示的每个字节前面都有反斜杠:

\1B\C1\93\F8\25\32\72\4E\8B\48\48\62\BB\44\49\7A
例如,您的GUID为:F893C11B-3225-4E72-8B48-4862BB44497A。首先,必须将其转换为长度为16的binary16类型字节数组,然后转换为十六进制字符串,最后插入反斜杠,如上面的示例所示:

declare @g uniqueidentifier = 'F893C11B-3225-4E72-8B48-4862BB44497A';
declare @gs nvarchar(max);

set @gs = CONVERT(nvarchar(max), CONVERT(binary(16), @g), 2);

declare @c int = 16;
while @c > 0
begin
set @c = @c - 1;
set @gs = STUFF(@gs, (2 * @c) + 1, 0, '\');
end;

declare @q nvarchar(max) = 
'select * from openquery(AD, 
'' select cn from ''''LDAP://DC=domain,DC=com'''' 
where objectGUID = ''''' + @gs + '''''  
'')';

exec(@q);
上述代码创建以下查询:

select * from openquery(AD, 'select cn from ''LDAP://DC=domain,DC=com'' where objectGUID = ''\1B\C1\93\F8\25\32\72\4E\8B\48\48\62\BB\44\49\7A'' ')

@user1633947包含变量时,引号太多。值本身不会被引用。您有4个单引号,可以转换为2个单引号,但它已经在字符串中,因此等同于字符串中的转义引号。也就是说,您没有包括@var的值,而是说WHERE objectGUID='++@var+',它正在查找+@var+的字符串文本。我已经用正确的语法更新了我的答案。好吧,既然你提到它,那听起来很明显;-。它一定是太累了,名字的GUID部分没有被拾起是的,我同意。如果这有效,我将+1。