SQL 服务器成功创建了一个调用不存在的函数的存储过程

SQL Server succeedes creating a stored procedure that invokes a NON-EXISTING function

在 SQL Server 2017 上测试。如果我创建一个过程(在 SSMS 或 sqlcmd 中)包含静态 SQL 命令引用 不存在的函数:

CREATE PROCEDURE mytest
AS
BEGIN
    DECLARE @tableVar TABLE(FIELD_1 INT, FIELD_2 VARCHAR(10))

    -- I am referencing a function that does not exist
    INSERT @tableVar 
        SELECT * FROM dbo.I_DO_NOT_EXISTS()
END
GO

Return 消息是:

Commands completed successfully.

这是一个很奇怪的行为!

只有当我尝试 运行 mytest 时,我才收到错误消息:

exec dbo.mytest

Msg 208, Level 16, State 1, Procedure dbo.mytest, Line 10 [Batch Start Line 16]
Invalid object name 'dbo.I_DO_NOT_EXISTS'.

而如果我尝试使用 exec 编译调用不存在的函数的过程:

CREATE PROCEDURE mytest
AS
BEGIN
    -- I am executing a function that does not exist
    EXEC dbo.I_DO_NOT_EXISTS
END
GO

我在编译时收到警告

The module 'mytest' depends on the missing object 'dbo.I_DO_NOT_EXISTS'. The module will still be created; however, it cannot run successfully until the object exists.

后一种回答对我来说似乎是正确的方法。

是否有任何选项可以对 SQL 命令引用的函数执行存在性检查?

如果 SP 验证是您的objective。您可以在创建 SP 后执行此操作。创建 SP 后,找到 SP 引用的所有对象。然后检查引用对象是否存在

运行 创建 SP 后的查询并检查 refrenced_id 是否为 NULL。如果它为空,则该特定对象不存在,您将在 SP 执行期间收到对象不存在错误。希望这可以帮助!我做了一个小测试,请在下面找到代码:

CREATE PROC TestSP
AS
BEGIN
    -- SPLIT function does not exists in the Database
    select * from  dbo.SPLIT('a,b,c,d',',')
    --Salary Table exists in the Database
    SELECT [Name],[salary]  FROM [dbo].[salary]
END

SELECT OBJECT_NAME(d.referencing_id) AS referencing_name, o.type_desc referencing_object_type,
 d.referenced_entity_name, d.referencing_id,d.referenced_id
FROM sys.sql_expression_dependencies d 
JOIN sys.objects o ON d.referencing_id = o.[object_id]
Where OBJECT_NAME(d.referencing_id) like '%TestSP%'

Click to see the Output of above query as Image