2008-10-09 103 views
7

我作为非SA用户'bhk'登录到SQL Server 2005数据库,该用户只是“公共”服务器角色的成员。以下代码尝试在由用户'bhk'调用的存储过程中执行。这行代码...DBCC CHECKIDENT在临时表上抛出权限错误,导致用户错误

TRUNCATE TABLE #Table1 
DBCC CHECKIDENT('#Table1', RESEED, @SequenceNumber) WITH NO_INFOMSGS 

原因这个错误...

用户 '客户' 没有权限 运行DBCC CHECKIDENT为对象
'#Table1__00000000007F'。

我知道运行DBCC CHECKIDENT所需的权限...
来电必须拥有该表,或者是sysadmin固定服务器角色的成员,db_owner固定数据库角色,或者db_ddladmin固定的数据库角色。

所以我有两个问题:

  1. 由于“BHK”被调用存储 过程,创建一个临时表 ,不应该“BHK”是所有者 和被允许运行DBCC CHECKIDENT?
  2. 为什么错误 消息返回该用户'guest' 没有权限?据我所知,我不是 作为'客人'登录。

任何帮助将不胜感激。

回答

6

这里是一个替代的解决方案,如果你需要重新播种逾1

TRUNCATE #Table1 

SET IDENTITY_INSERT #Table1 ON 

INSERT INTO #Table1 (TableID) -- This is your primary key field 
VALUES (@SequenceNumber - 1) 

SET IDENTITY_INSERT #Table1 OFF 

DELETE FROM #Table1 

这是什么做的是将IDENTITY上临时表中的序列号,可能工作,允许您添加一个带有显式ID的行。然后你可以删除这一行,但是进一步的插入应该从最后一个序列号开始。

3

您写道:

“主叫方必须拥有该表,或者是sysadmin固定服务器角色 固定的db_owner的 成员。”

所以(如果不是bug),根据Lieutenant Columbo's无可挑剔的逻辑,每个前提必须是假的。这意味着,即使他创建了它,调用者也不拥有该表,即

实际上,默认情况下,似乎在tempd 中创建的所有对象都由dbo所有。你可以检查它,如果你不按照查询分析器:使用低权限用户

  1. 连接到数据库
  2. 执行:CREATE TABLE #NotMyTable (TestID int identity)
  3. 连接到相同的SQL Server tempdb中作为DBO
  4. 执行:SELECT user_name(uid) FROM sysobjects WHERE name LIKE '#NotMyTable%'

你会看到,DBO是临时表的所有者。

那么,有什么可以解决的?

(前言:我不喜欢那种操控的,但智力刺激是推动我... ;-)

所以,你可以另写存储过程,而更新的UID在tempdb的sysobjects中添加到您的用户的值(shiver!)。我只在查询分析器中测试过它。更新后,我可以执行您的DBCC CHECKIDENT命令。

+0

虽然这可能会起作用,但我同意不喜欢那种操纵。 – 2008-10-22 16:17:12

1

执行TRUNCATE和CHECKIDENT命令的备用解决方案是简单地删除并重新创建临时表。例如。

DROP TABLE #Table1 

CREATE TABLE #Table1 
(
    .... 
) 

虽然这可能不是最有效的解决方案。

+0

你是对的。但是,在我的情况下,目标是将标识列重置为除1之外的其他值。Drop/Create仅将列重置为1,并且似乎不允许变量作为IDENTITY SEED参数的值。 – 2008-10-13 15:01:03

2

您可以通过完全限定tempdb表来完成此操作。

DBCC CHECKIDENT([tempdb..#Table1], RESEED, @SequenceNumber) WITH NO_INFOMSGS 
1

我刚碰到这个。我得到的答案是为tempdb数据库中的相关帐户提供权限,在这些数据库中创建这些表。

+0

我通过以sa身份登录并检查我正在使用的登录名来解决此问题,以确保它具有映射到具有ddladmin成员身份的tempdb中的用户 – jocassid 2016-09-01 20:37:00