如何检测SQL Server中不可执行的用户定义函数及引用的无效表?
检查SQL Server中所有用户定义函数(UDF)的可执行性
针对SQL Server中删除被UDF引用的表/视图不会给出提示、导致UDF执行失败的问题,有两种可靠的检查方法:
方法一:通过系统视图检查无效依赖
利用系统视图查询UDF引用的对象是否存在,无需执行UDF,安全高效:
SELECT SCHEMA_NAME(udf.schema_id) AS UDF_Schema, udf.name AS UDF_Name, ref.referenced_entity_name AS Missing_Referenced_Object FROM sys.objects udf JOIN sys.sql_expression_dependencies ref ON udf.object_id = ref.referencing_id WHERE udf.type IN ('FN', 'IF', 'TF') -- 覆盖标量、内联表值、多语句表值函数 AND ref.referenced_id IS NULL; -- 被引用对象不存在时,referenced_id为NULL
该查询会直接列出所有引用了已删除或不存在对象的UDF,快速定位问题。
方法二:批量执行测试UDF
如果UDF中包含动态SQL或系统视图未捕获的依赖,需要实际执行UDF来验证可执行性。通过动态SQL生成测试语句,结合TRY_CATCH捕获错误:
测试标量UDF
DECLARE @testSql NVARCHAR(MAX) = ''; SELECT @testSql += 'BEGIN TRY SELECT ''' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + ''' AS UDF_Name, ''执行成功'' AS Status; SELECT ' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + '(DEFAULT); -- 用默认参数,无默认值需替换为合理测试值 END TRY BEGIN CATCH SELECT ''' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + ''' AS UDF_Name, ERROR_MESSAGE() AS Error_Info; END CATCH GO ' FROM sys.objects o WHERE o.type = 'FN'; EXEC sp_executesql @testSql;
测试表值UDF
DECLARE @testSql NVARCHAR(MAX) = ''; SELECT @testSql += 'BEGIN TRY SELECT ''' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + ''' AS UDF_Name, ''执行成功'' AS Status; SELECT * FROM ' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + '(DEFAULT); -- 用默认参数,无默认值需替换为合理测试值 END TRY BEGIN CATCH SELECT ''' + QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(o.name) + ''' AS UDF_Name, ERROR_MESSAGE() AS Error_Info; END CATCH GO ' FROM sys.objects o WHERE o.type IN ('IF', 'TF'); EXEC sp_executesql @testSql;
注意:若UDF没有默认参数,需将语句中的DEFAULT替换为符合参数类型的测试值,避免因参数错误导致误判。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

