T-SQL OBJECT_ID始终返回NULL,即使存在元数据并且用户具有正确的权限



当我用有效的对象名称调用OBJECT_ID时,我总是得到null。例如

use [My-Database];
declare @objectId int;
SELECT * FROM sys.objects WHERE name = 'DF_FieldStatusTypes_DisplayOrder'
SELECT @objectId = object_id FROM sys.objects WHERE name = 'DF_FieldStatusTypes_DisplayOrder'
SELECT @objectId
SELECT object_name(@objectId)
SELECT object_id(object_name(@objectId))
SELECT object_id('DF_FieldStatusTypes_DisplayOrder')

产生的结果如下:

(1) DF_FieldStatusTypes_DisplayOrder| 753437758 | NULL | 5 | 241435934 | D | DEFAULT_CONSTRAINT | 2020-10-17 11:08:13.520 | 2020-10-17 11:08:13.520 | 0 | 0 | 0  
(2) 753437758  
(3) DF_FieldStatusTypes_DisplayOrder  
(4) NULL
(5) NULL

结果1到3是准确的,但4和5总是返回NULL。我下面引用的Stack问题类似,并引用了微软关于OBJECT_ID的文章,其中指出:

。。。元数据发射,OBJECT_ID等内置函数可能返回如果用户对该对象没有任何权限,则为NULL。

但是,在文章的OBJECT_NAME 的"例外"部分中也说明了完全相同的信息

然而,在我的情况下,OBJECT_NAME函数被成功调用,并且OBJECT_ID总是返回null。

我错过了什么?


类似问题

为什么object_id总是返回null?

这是一个暗算,但我怀疑原因的提示在您的第一个结果集中。schema_id的值为5,这意味着它不在dbo模式中。因此,我怀疑您的默认模式是,而不是所述对象所在的模式。

采取以下声明:

CREATE TABLE dbo.SomeTable (ID int
CONSTRAINT DF_ID
DEFAULT 0);
GO
DECLARE @objectId int;
SELECT *
FROM sys.objects
WHERE name = 'DF_ID';
SELECT @objectId = object_id
FROM sys.objects
WHERE name = 'DF_ID';
SELECT @objectId;
SELECT OBJECT_NAME(@objectId);
SELECT OBJECT_ID(OBJECT_NAME(@objectId));
SELECT OBJECT_ID('DF_ID');
GO
DROP TABLE dbo.SomeTable;

这将为所有数据集返回一个非NULL值。db<gt;小提琴

现在让我们使用一个不同的模式,这不是我的默认模式。

CREATE SCHEMA another;
GO
CREATE TABLE another.SomeTable (ID int
CONSTRAINT DF_ID
DEFAULT 0);
GO
DECLARE @objectId int;
SELECT *
FROM sys.objects
WHERE name = 'DF_ID';
SELECT @objectId = object_id
FROM sys.objects
WHERE name = 'DF_ID';
SELECT @objectId;
SELECT OBJECT_NAME(@objectId);
SELECT OBJECT_ID(OBJECT_NAME(@objectId));
SELECT OBJECT_ID('DF_ID');
GO
DROP TABLE another.SomeTable;
GO
DROP SCHEMA another

另一方面,这会返回您所得到的结果:db<gt;小提琴

那么,为什么会这样呢?OBJECT_NAME只返回对象的名称,而不返回名称和模式。因此,DF_ID将被推断为模式dbo上的对象DF_ID;在CCD_ 9模式上不存在具有该名称的这样的对象。

如果包含架构名称,则会得到以下结果:db<gt;小提琴

当然,您永远不会使用对象id来获取对象名称,也不会使用对象名称,所以您遇到的问题有点荒谬。

您缺少架构。从sys.objects的结果可以看出该对象属于schema_id = 5。所以试试:

SELECT OBJECT_ID(SCHEMA_NAME(5) + N'.' + OBJECT_NAME(@objectId));

我缺少什么?

sys.objects查询不考虑对象模式,并且将返回行,而不管表模式如何。当表不在默认架构中并且对象名称不合格时,OBJECT_ID将返回NULL

尝试对约束名称进行架构限定。dbo模式示例:

SELECT OBJECT_ID('dbo.DF_FieldStatusTypes_DisplayOrder');

最新更新