首页 > 解决方案 > SQL Server - 薛定谔的观点

问题描述

我无法创建/更改 VIEW,因为它已经存在。我也不能删除相同的视图,因为它不存在!

首先,我是SQL Server 2012 上的SA 。

CREATE VIEW [dbo].[some_name]

数据库中已经有一个名为“some_name”的对象。

DROP VIEW [dbo].[some_name]

无法删除视图“dbo.some_name”,因为它不存在或您没有权限。

SELECT OBJECT_ID(N'dbo.some_name', N'V')
SELECT OBJECT_ID('dbo.some_name', 'V')
SELECT OBJECT_ID(N'dbo.some_name')
SELECT OBJECT_ID('dbo.some_name')
SELECT OBJECT_ID(N'some_name')
SELECT OBJECT_ID('some_name')

NULL(对于每个查询)

SELECT * FROM sys.objects WHERE name LIKE '%some_name%'
SELECT * FROM sys.objects WHERE name ='some_name'
SELECT * FROM sys.objects WHERE name = N'some_name'

空结果(对于每个查询)

SELECT * FROM fn_my_permissions(N'dbo.some_name','OBJECT')
SELECT * FROM fn_my_permissions('dbo.some_name','OBJECT')
SELECT * FROM fn_my_permissions(N'some_name','OBJECT')
SELECT * FROM fn_my_permissions('some_name','OBJECT')
SELECT * FROM fn_my_permissions(N'some_name','VIEW')
SELECT * FROM fn_my_permissions('some_name','VIEW')

空结果(对于每个查询)

'some_name' 上的 Alt+F1:

对象“some_name”在数据库“X”中不存在或对该操作无效。

EXEC sp_rename 
@objname = 'other_name',
@newname = 'some_name'

错误:新名称“some_name”已用作对象名称,并会导致不允许的重复。

EXEC sp_rename 
@objname = 'some_name',
@newname = 'other_name'

在当前数据库“X”中找不到名称为“some_name”的项目,因为@itemtype 输入为“(null)”。

现在有一些有趣的事情。如果我运行:

DROP FUNCTION [dbo].[some_name]
DROP SYNONYM [dbo].[some_name] 
DROP TABLE [dbo].[some_name]
DROP TRIGER[dbo].[some_name]
DROP TYPE [dbo].[some_name]
DROP VIEW [dbo].[some_name]

只收到 5条消息:

无法删除 [FUNCTION, SYNONYM, TABLE, TRIGGER, TYPE] 'dbo.some_name',因为它不存在或您没有权限。(没有提到 VIEW)

但是,如果我将 View 命令移到顶部:

DROP VIEW [dbo].[some_name]
DROP FUNCTION [dbo].[some_name]
DROP SYNONYM [dbo].[some_name] 
DROP TABLE [dbo].[some_name]
DROP TRIGER[dbo].[some_name]
DROP TYPE [dbo].[some_name]

正如预期的那样,我收到6 条消息。

请帮忙。

更新

在几个 CHECKDB 命令之后,我发现似乎是问题所在。正如怀疑的那样,这种观点处于不一致的状态。通过 DBCC 命令日志,我得到了它的 object_id。它不存在于 sys.objects 上,但它存在于 sys.columns 上。因此,我的数据库中有一些孤立列,这表明创建或删除此对象时失败。

因此,通过运行 DBCC CHECKCATALOG(和其他一些 DBCC 命令),我得到了以下消息:

消息 3853,状态 1:sys.sql_dependencies 中行 (class=0,object_id=990678627,column_id=0,referenced_major_id=859202161,referenced_minor_id=42) 的属性 (referenced_major_id=859202161,referenced_minor_id=42) 没有匹配的行 ( sys.columns 中的 object_id=859202161,column_id=42)。

Msg 8956, Level 16, State 1, Line 1 索引行 (1:123:12) 的值 (nsclass = 0 and nsid = 1 and name = 'some_name') 指向由 (RID = (1: 456:45))。

解决方案

0 - 备份您的数据库。

1 - 在单用户模式下重新启动服务器(-m 参数)

2 - 将数据库设置为单用户模式:

ALTER DATABASE X
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
GO

3 - 运行带有修复选项的 CHECKDB 命令。就我而言,它是:

DBCC CHECKDB (X,REPAIR_REBUILD)

4 - 将数据库设置回多用户模式

ALTER DATABASE X
SET MULTI_USER
WITH ROLLBACK IMMEDIATE;
GO

“X”是数据库的名称。我不确定步骤 0 和 1 是否真的有必要,但安全总比抱歉好。

您可以在以下位置找到有关 CHECKDB 命令及其修复选项的更多信息:DBCC CHECKDB

标签: sql-server

解决方案


根据您的错误消息,我知道dbo.some_name存在,但是您没有足够的权限查看 dbo.some_name。

sys.objects将仅显示您有权查看的对象。MSDN 参考

权限

目录视图中元数据的可见性仅限于用户拥有或已被授予某些权限的安全对象。

您可以通过运行以下查询来查看您对对象拥有的权限:

SELECT * FROM fn_my_permissions('dbo.some_name','OBJECT')

您需要拥有 CONTROL 权限才能删除它。您需要具有 ALTER 权限才能重命名对象。

更新

您能否再次检查您是否是服务器级别的 sysadmin 角色和 db 级别的 db_owner 角色的一部分(系统管理员以 db_owners 身份进入数据库)。

use database_name
go
SELECT Is_srvrolemember('sysadmin')
select IS_ROLEMEMBER('db_owner')

推荐阅读