我接近完成这项工作。我需要在我们的Intranet上识别用户。我需要将该用户的objectGUID
存储在SQL Server数据库表中,并能够再次检索该记录。我有几个不同的应用程序,PHP,ASP Classic和ASP.Net。我认为在SQL Server中执行AD查找可能最简单。
我可以使用本教程http://sql.dzone.com/news/querying-active-directory-thro
中的步骤连接到AD我可以检索objectGUID
以及我需要的任何其他内容,但我不确定如何将objectGUID
存储在数据库中或如何使用objectGUID
查询数据库。< / p>
我认为它是数据类型(128长度字节数组?)并且需要转换,但我不知道该怎么做。
从活动目录中选择记录并插入表中显示插入的数据类型objectGUID为varbinary(256)
select *
into temp_table
from openquery(adsi, '
select givenName,
sn,
sAMAccountName,
objectGUID
from ''LDAP://dc=somedomain,dc=com''
where sAMAccountName = ''some_user''
')
为了测试,我尝试使用从上面的temp_table中检索到的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,键入equals varchar
所以也许我接近错误的语法,或者仍然是数据类型问题?
提前致谢。
答案 0 :(得分:1)
要在单个查询中从AD检索数据,当您请求特定的对象GUID或多个GUID时,有一种方法可以使用where
子句代替from LDAP://<GUID=your guid>
表达式(在单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
。首先,您必须将其转换为binary(16)
类型(长度为16的字节数组),然后转换为十六进制字符串,最后像上面的示例一样插入反斜杠:
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'' ')
答案 1 :(得分:0)
您是否在TSQL中尝试过CAST
或CONVERT
? http://msdn.microsoft.com/en-us/library/ms187942.aspx有几个例子。
答案 2 :(得分:0)
目前还不清楚你是什么意思&#34;如何使用objectGUID&#34;查询数据库,但如果你想知道确切的数据类型,有两种方法:
如果您至少使用SQL Server 2012,则可以尝试sp_describe_first_result_set。它有几个限制因此不适用于所有情况。
您可以将结果转储到临时表,然后检查其结构:
SELECT fields
INTO #tmp
FROM openquery(...);
EXEC tempdb.dbo.sp_help '#tmp';
在创建用于存储值的列或声明局部变量时,使用返回的任何数据类型(可能是BINARY(128)
或VARBINARY(128)
)。
修改强>
所以我们现在知道objectGUID
是一个VARBINARY(256)。为了在查询中正确使用它,请从已转义的字符串中的转义字符串中删除三组单引号。此外,我们需要将VARBINARY转换为VARCHAR,以便它可以连接到动态SQL字符串中。使用CONVERT
功能时,请务必使用&#34;样式&#34;将十六进制数字转换为十六进制数字字符串的1
的数量(即&#34; 0x12D5&#34;);如果你没有指定&#34;样式&#34;默认操作是转换为由这些十六进制数字表示的字符(即&#34; Hello!&#34;)。
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);
答案 3 :(得分:0)
我还在我的项目中将AD中的objectGUID存储到SQL服务器中,并使用uniqueidentifier。 (但是我不使用OpenQuery,而是使用Windows服务不断从AD同步并填充数据库。)
虽然从AD对象获取的对象出现为二进制数组(varbinary),但是 它实际上代表一个GUID,SQL中相应的类型是uniqueidentifier 并且GUID仅为16字节(128位)。
这未经过测试,但请尝试以下方式:
Select CONVERT(uniqueIdentifier,objectGUID) as Id, ...
FROM OpenQuery(ADSI,
'SELECT objectGUID, ...
FROM ...
WHERE...')
答案 4 :(得分:0)
我无法在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)