IF (OBJECT_ID('FK', 'F') IS NOT NULL) doesn't work but IF EXISTS() does? 如果(OBJECT_ID('FK','F')不为空)不起作用,但IF EXISTS()起作用吗?

5 浏览
0 Comments

IF (OBJECT_ID('FK', 'F') IS NOT NULL) doesn't work but IF EXISTS() does? 如果(OBJECT_ID('FK','F')不为空)不起作用,但IF EXISTS()起作用吗?

使用SQL Server 2014,这个查询似乎不起作用(即,不删除外键)

IF (OBJECT_ID('FK', 'F') IS NOT NULL)
BEGIN
    ALTER TABLE my_table 
    DROP CONSTRAINT [FK]
END

但是这个可以

IF EXISTS(
SELECT  *
FROM    sys.foreign_keys
WHERE   name = 'FK')
BEGIN
    ALTER TABLE my_table 
    DROP CONSTRAINT [FK]
END

我正在努力理解为什么。特别是因为第一个查询曾经是有效的。

运行此查询会返回带有外键的行(类型为F

select * from dbo.sysobjects o where o.type = 'F' and name = 'FK'

但是运行此查询不会打印出找到的外键语句

IF (OBJECT_ID('FK', 'F') IS NOT NULL)
BEGIN
    PRINT 'Found foreign key'
END

评论中建议的查询结果

select LEN(name) as 'Len', CAST(name as varbinary(MAX)) as AsBinary, name from dbo.sysobjects o 
where o.type = 'F' and name = 'my_fk_name'

给我返回了

108 | 0x46004B005F0049........006F006E0049006400 | my_fk_name

select id from dbo.sysobjects o 
where o.type = 'F' and name = 'my_fk_name'
select OBJECT_NAME(TheObjectId)

给我返回了

my_fk_name

0
0 Comments

问题的原因是:根据OBJECT_ID函数的文档,该函数只能搜索“模式范围内”的对象,也就是直接依赖于某个模式的对象。但是你正在使用它来查询一个外键,外键依赖于其底层表而不是任何模式,因此永远无法找到外键。

解决方法是:使用IF EXISTS()语句查询外键的存在性,这样无论外键是否存在,都能找到它。事实上,MSDN上的示例几乎与你的代码非常相似,只不过是针对触发器而不是外键而已。如果你进一步阅读文档,你会发现外键是一种被接受的对象类型。

你应该指定外键的模式。参考以下语法:OBJECT_ID('[数据库名].[模式名].[|模式名.]对象名'[, '对象类型'])

0