2012-03-07 148 views
2

我键入下面的T-SQL代码到一个SQL查询窗口的行为的真正的奥秘:与SUSER_SID在简单的T-SQL查询

-- Get the SUSER_SID standalone 
SELECT SUSER_SID('sql_someuser') AS SUSER_SID_OF_SQL_SOMEUSER 

-- Get the SUSER_SID as part of a more complex query (should be the same, right?) 
SELECT UserSid, UserId FROM User..UserSidToUserId 
UNION ALL 
SELECT SUSER_SID('sql_someuser'),12345 

下面是结果集,我得到:

enter image description here

第二个结果集的前两行直接来自UserSidToUserId表。但最后一行UserId12345UNION ALL的第二个查询所添加的那个,UserSid的第二个调用SUSER_SID生成的那一个完全相同的用户名是不同的!

更新: 正是如此,没有混乱,这里是UserSidToUserId表的定义:

CREATE TABLE dbo.UserSidToUserId 
(
    UserSid uniqueidentifier NOT NULL, 
    UserId int NOT NULL, 
) 

如何两个调用使用相同的用户名SUSER_SID产生的结果取决于上下文中使用SUSER_SID,因为它是一个独立于上下文的绝对调用?

回答

2

您的UNION正在将第二个字符串转换为字符串,但可能您已经定义了User..UserSidToUserId.UserSid。注意不同的答案:

SELECT SUSER_SID(), CONVERT(VARCHAR(64), SUSER_SID()); 
+1

转换'SUSER_SID()'的'VARCHAR'产生不可打印垃圾......这不是问题。我还将'UserSidToUserId'表的定义添加到原始问题中。 – 2012-03-07 17:19:35

+0

它仍然是一个数据类型的差异(我只是不知道你的基表是如何定义的)。你为什么使用'UNIQUEIDENTIFIER'? 'SUSER_SID()'不是一个GUID - 它返回'VARBINARY(85)'。因此,为了与您的表格匹配,基于数据类型优先级,您的联合会尝试将其'SUSER_SID()'调用转换为GUID。如果你希望它们看起来一样,那么改变你的表定义为'VARBINARY(85)',或者在调用'SUSER_SID()'时直接使用'CONVERT'。 – 2012-03-07 17:26:29

+0

根据最新评论,您的解决方案是正确的。所以,我会改变我的表格定义,并且我已经接受了你的答案......但是,我引用了SQL Server对SUSER_ID的帮助:“如果登录是SQL Server登录,则SID映射到GUID。 – 2012-03-07 17:33:55

0

解决方案是事实证明,所述UNIQUEIDENTIFIER字节顺序是从一个BINARY类型的不同,在主机字节顺序一些零件和一些以网络字节顺序。为了使两个结果的比赛,你必须做的:

SELECT (CONVERT(UNIQUEIDENTIFIER,SUSER_SID('sql_someuser'))) 
     AS SUSER_SID_OF_SQL_SOMEUSER_AS_UUID 

现在它将会输出的最后一行匹配:

-- Get the SUSER_SID as part of a more complex query (should be the same, right?)  
SELECT UserSid, UserId FROM User..UserSidToUserId  
UNION ALL  
SELECT SUSER_SID('sql_someuser'),12345