由于对象不存在或您没有权限,无法找到该对象。 SQLServer 中出现错误

我有一个数据库,并有一个 Sql 脚本来添加一些字段到数据库中名为“ Products”的表中。

但是当我执行这个脚本时,我会得到以下错误:

Cannot find the object "Products" because it does not exist or you do not have permissions

为什么会出现错误,我应该做什么来解决它?

251559 次浏览

您确定正在对正确的数据库执行脚本吗?在 SQLServerManagement 工作室中,您可以在其中一个工具栏的下拉框中更改正在运行查询的数据库,或者您可以使用以下命令启动查询:

USE SomeDatabase

执行这个脚本的用户是否看到了那个表? ?

select top 1 * from products

这个有什么结果吗?

如果是: 这个用户是否有权限修改表,比如执行像 ALTER TABLE这样的 DDL 脚本?通常,普通用户没有这种提升的权限。

您可以右键单击过程,选择属性,并查看哪些权限授予您的登录 ID。然后,您可以手动勾选“ Execute”并更改进程的权限。

或者这样写:

GRANT EXECUTE ON OBJECT::dbo.[PROCNAME]
TO [ServerInstance\user];


GRANT ALTER ON OBJECT::dbo.[PROCNAME]
TO [ServerInstance\user];

我找到了这一切发生的原因。用户拥有适当的权限,但存储过程包含 TRUNCATE语句:

TRUNCATE TableName

由于 TRUNCATE在不记录日志的情况下删除项,因此您(显然)需要更高的权限来执行包含它的存储过程。我们把声明改为:

DELETE FROM TableName

错误消失了!

也有可能您已经在登录模式中创建了“ Products”,并试图在不同的模式(可能是 dbo)中执行相同的命令

解决此问题的步骤

1)开设管理工作室 2)在资源管理器中定位对象并识别对象所在的模式?(它是对象名称前面的文本)。在下面的图像中,它的“ dbo”和我的对象名称是动作状态

highlighted part is schema name

如果你把它看作是“你的公司在你的逻辑里”,那么你应该这样看 您可以修改该特定架构的权限,而不是任何其他架构的权限。

你可参阅 “ SQLServer 中的所有权和用户架构分离”

这也可能是由于在引用诸如 [dbo.Product]而不是 [dbo].[Product]之类的表时输入错误造成的。

在我的例子中,我使用的用户与我预期的用户不同。

我的代码将 'DRIVER={SQL Server};SERVER=...;DATABASE=...;Trusted_Connection=false;User Id=XXX;Password=YYY'作为连接字符串传递给 pypyodbc.connect(),但它最终连接到 Windows 用户的凭据,即 运行脚本,而不是连接字符串中的 User Id=

(我使用 SQL Server Profiler 进行了验证,并在连接字符串中放入了无效的 uid/密码组合——这没有导致预期的错误)。

我决定不再深究这个问题,因为切换到这种更好的连接方式解决了这个问题:

conn = pypyodbc.connect(driver='{SQL Server}', server='servername',
database='dbname', uid='userName', pwd='Password')

我一直在尝试将一个表从 PROD 复制到 DEV,但是得到了一个错误: “找不到对象 X,因为它不存在或者您没有权限。”

但是,该表确实存在,而且我以 sa 的身份运行,因此我确实拥有权限。

实际上问题出在约束条件上。几个月前,我把 DEV 上的表重新命名为 old _ XXX。但是当我试图从 PROD 中复制原始的时候,Defaut Constraint 名称发生了冲突。

错误消息具有误导性

分享我的案子,希望能有所帮助。

以我在 MY_PROJ.Database->MY_PROJ.Database.sqlproj的情况,我不得不这样说:

<Build Include="dbo\Tables\MyTableGeneratingScript.sql" />

这可能是权限问题。用户至少需要 ALTER 权限才能截断表。 另一个选项是调用 DELETE FROM 而不是 TRUNCATE TABLE,但这个操作比较慢,因为它写入日志文件,而 TRUNCATE 不写入日志文件。

所需的最低权限是 TABLE _ name. TRUNCATETABLE 上的 ALTER 默认为表所有者的权限,sysadmin 的成员已修复 服务器角色,以及 db _ owner 和 db _ ddladmin 固定数据库角色, 但是,您可以合并 TRUNCATE 模块(如存储过程)中的 TABLE 语句,并授予 使用 EXECUTEAS 子句对模块具有适当的权限。

在我的示例中,本地主机上的 sql 服务器版本高于生产服务器上的 sql 服务器版本,因此从本地主机生成的脚本中添加了一些新变量。这首先导致了创建表时的错误。 由于创建表失败,对“ NONEXISITING”表的后续查询也失败。 幸运的是,在一长串 sql 错误中,我发现这个“ OPTIMIZE _ FOR _ SEQUENTIAL _ KEY = OFF”是脚本中导致我的问题的新变量。我做了一个搜索和替换,错误消失了。 希望能帮到别人。

在脚本中查找任何 DDL 操作。 也许用户没有运行更改的访问权限。

对我来说是 SET IDENTITY_INSERT tblTableName ON

您可以为整个数据库添加 db_ddladmin,也可以仅为表添加 db_ddladmin来解决这个问题(或者更改脚本)

-- give the non-ddladmin user INSERT/SELECT as well as ALTER:
GRANT ALTER, INSERT, SELECT ON dbo.tblTableName TO user_name;

TRUNCATE 语句是我的第一个问题,很高兴在这里找到了解决方案。但是我正在使用 SSIS 并尝试从另一个数据库加载数据,它失败了,在使用 IDENTITY 创建自动递增 ID 的任何表上都出现了同样的错误。如果我自己编写脚本,我首先需要使用命令 设置 IDENTITY _ INSERT < em > tablename ON,然后在表更新完成后使用 设置 IDENTITY _ INSERT < em > tablename OFF。但是这需要对表的 ALTER 权限,而我没有这个权限。因此,在 SSIS 中加载表时会出现错误消息(即使前一步刚刚从表中删除了所有数据)

例如,在 Go 中使用类似于 GORM (https://gorm.io/)的 ORM 时,会收到此错误。

当您尝试创建结构并意外地传递 ID (主键)时,尽管它是自动插入的。

像 Visual Studio Code 这样的丰富特性 IDE 使这种错误很容易发生:

if tx := db.Create(&myStruct{
Ts:                Time.Now(),
ID:                42,
}); tx.Error != nil {
t.Fatal(tx.Error)
}

您仍然可以通过 VisualStudio 代码使用自动填充,但是删除模型主键的条目:

if tx := db.Create(&myStruct{
Ts:                Time.Now(),
}); tx.Error != nil {
t.Fatal(tx.Error)
}