DBCC CHECKIDENT在临时表上为错误的用户抛出权限错误

时间:2008-10-09 15:53:15

标签: sql-server-2005 stored-procedures permissions temp-tables

我作为非sa用户“bhk”登录到SQL Server 2005数据库,该用户只是“公共”服务器角色的成员。以下代码尝试在用户'bhk'调用的存储过程中执行。这行代码......

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. 为什么会出错     消息返回用户'来宾'     没有许可?据我所知,我不是     以“访客”身份登录。
  3. 非常感谢任何帮助。

5 个答案:

答案 0 :(得分:7)

这是一个替代解决方案,如果您需要使用大于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_INSERT,以允许您添加具有显式ID的行。然后,您可以删除此行,但是进一步的插入应该从最后一个序列号开始。

答案 1 :(得分: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%'
  5. 您会看到dbo是临时表的所有者。

    那么,什么是解决方案?

    (前言:我不喜欢那种操纵,但智力刺激正在推动我......; -

    因此,您可以编写另一个存储过程,将tempdb的sysobjects中的UID更新为您的用户值( shiver!)。我只在查询分析器中测试过它。更新后,我可以执行您的DBCC CHECKIDENT命令。

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

执行TRUNCATE和CHECKIDENT命令的另一种解决方案是简单地删除并重新创建临时表。 E.g。

DROP TABLE #Table1

CREATE TABLE #Table1
(
   ....
)

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

答案 4 :(得分:1)

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