T-SQL OBJECT_ID 总是返回 NULL,即使存在元数据并且用户具有正确的权限
T-SQL OBJECT_ID always returning NULL even though metadata exists and user has correct permissions
当我使用有效的对象名称调用 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 总是 return NULL。我在下面引用的 Stack 问题是类似的,并引用了 Microsoft article for OBJECT_ID 的内容:
... metadata-emitting, built-in functions such as OBJECT_ID may return
NULL if the user does not have any permission on the object.
但是,完全相同的信息在 article for OBJECT_NAME
的例外部分下说明
然而,在我的例子中,OBJECT_NAME 函数被成功调用并且 OBJECT_ID 总是 returns null。
我错过了什么?
类似问题
Why does object_id always returns null?
您缺少架构。 sys.objects
结果显示该对象属于 schema_id = 5
。所以尝试:
SELECT OBJECT_ID(SCHEMA_NAME(5) + N'.' + OBJECT_NAME(@objectId));
What am I missing?
您的 sys.objects
查询不考虑对象架构,并且无论 table 架构如何,都会 return 行。 OBJECT_ID
将 return NULL
当 table 不在您的默认架构中并且对象名称不合格时。
尝试schema-qualifying约束名称。 dbo
架构示例:
SELECT OBJECT_ID('dbo.DF_FieldStatusTypes_DisplayOrder');
这是暗中刺探,但我怀疑您的第一个结果集中暗示了原因。 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;
这 returns 是所有数据集的非 NULL
值。 db<>fiddle
现在让我们使用不同的模式,这不是我的默认模式。
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
另一方面returns你得到的结果是:db<>fiddle
那么,这是为什么呢?好吧,OBJECT_NAME
只是 returns 对象的名称,而不是名称和模式。因此,DF_ID
将被推断为架构 dbo
上的对象 DF_ID
; dbo
模式中没有该名称的此类对象。
如果包含模式名称,您将得到结果:db<>fiddle
当然,你永远不会用object id,获取object name,获取object name,所以你的问题有点无厘头。
当我使用有效的对象名称调用 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 总是 return NULL。我在下面引用的 Stack 问题是类似的,并引用了 Microsoft article for OBJECT_ID 的内容:
... metadata-emitting, built-in functions such as OBJECT_ID may return NULL if the user does not have any permission on the object.
但是,完全相同的信息在 article for OBJECT_NAME
的例外部分下说明然而,在我的例子中,OBJECT_NAME 函数被成功调用并且 OBJECT_ID 总是 returns null。
我错过了什么?
类似问题
Why does object_id always returns null?
您缺少架构。 sys.objects
结果显示该对象属于 schema_id = 5
。所以尝试:
SELECT OBJECT_ID(SCHEMA_NAME(5) + N'.' + OBJECT_NAME(@objectId));
What am I missing?
您的 sys.objects
查询不考虑对象架构,并且无论 table 架构如何,都会 return 行。 OBJECT_ID
将 return NULL
当 table 不在您的默认架构中并且对象名称不合格时。
尝试schema-qualifying约束名称。 dbo
架构示例:
SELECT OBJECT_ID('dbo.DF_FieldStatusTypes_DisplayOrder');
这是暗中刺探,但我怀疑您的第一个结果集中暗示了原因。 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;
这 returns 是所有数据集的非 NULL
值。 db<>fiddle
现在让我们使用不同的模式,这不是我的默认模式。
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
另一方面returns你得到的结果是:db<>fiddle
那么,这是为什么呢?好吧,OBJECT_NAME
只是 returns 对象的名称,而不是名称和模式。因此,DF_ID
将被推断为架构 dbo
上的对象 DF_ID
; dbo
模式中没有该名称的此类对象。
如果包含模式名称,您将得到结果:db<>fiddle
当然,你永远不会用object id,获取object name,获取object name,所以你的问题有点无厘头。