8

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

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

导致此错误...

用户 'guest' 无权为对象
'#Table1__00000000007F' 运行 DBCC CHECKIDENT。

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

所以我有两个问题:

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

任何帮助将不胜感激。

4

5 回答 5

8

这是另一种解决方案,如果您需要使用大于 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 的行。然后您可以删除该行,但进一步的插入应该从最后一个序列号开始。

于 2008-10-13T15:39:05.857 回答
4

你写了:

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

所以(如果它不是错误的话),根据Columbo 中尉无可挑剔的逻辑,每个前提都必须是错误的。这意味着,调用者不拥有该表,即使他创建了它。

事实上,似乎在 tempd中创建的所有对象默认都归 dbo 所有。如果您在查询分析器中执行以下操作,您可以检查它:

  1. 使用低权限用户连接到您的数据库。
  2. 执行:CREATE TABLE #NotMyTable (TestID int identity)
  3. 连接到与 dbo相同的 SQL Server 的tempdb
  4. 执行:SELECT user_name(uid) FROM sysobjects WHERE name LIKE '#NotMyTable%'

您会看到 dbo 是临时表的所有者。

那么,有什么办法可以解决呢?

(前言:我不喜欢那种操纵,但智力刺激正在驱使我……;-)

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

于 2008-10-11T15:16:26.543 回答
3

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

DBCC CHECKIDENT([tempdb..#Table1], RESEED, @SequenceNumber) WITH NO_INFOMSGS
于 2011-02-08T17:00:03.267 回答
1

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

DROP TABLE #Table1

CREATE TABLE #Table1
(
   ....
)

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

于 2008-10-13T09:07:27.690 回答
1

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

于 2012-04-30T15:23:47.827 回答