0

假设我有一个 inline-tvf 函数(假设名称:cfn_test),其定义如下:

从表A中选择*;

现在,在创建时,TableA 的结构是:

colA,colB(此时数据类型无关紧要)

让我们也添加一些数据:

| colA | colB |
|   1  |  2   |

该应用程序使用“SELECT * FROM cfn_test()”,并获得:

| colA | colB |
|   1  |  2   |

现在的问题:

tableA的结构发生了变化,在colA和colB.Data之间插入了一个colC:

| colA | colC | colB |
|   1  |   3  |   2  |

该应用程序现在得到:

| colA | colB |
|   1  |  3   |

如果我运行 SSMS 生成的 alter function 脚本,而不进行任何更改,它现在会返回正确的结果。

我的问题:a)是否有可能根据文本中“select *”的存在以某种方式检测哪些函数需要“更新”(我认为这是错误行为的罪魁祸首)

b)如果我设计一个循环遍历所有现有函数的脚本(使用 [INFORMATION_SCHEMA].[ROUTINES] ),我能否以某种方式自动生成 SSMS 生成并运行它的“alter function”脚本,以便所有函数都更新为当前的底层架构?

4

1 回答 1

1

A) 您可以使用系统视图 -sys.sql_modulessys.sql_dependencies

您可以在其中sql_modules搜索对象(函数、过程、视图)的定义并找到您需要的模式。也许是这样的:

SELECT * FROM sys.sql_modules
WHERE definition LIKE '%TableA%' AND definition LIKE '%SELECT *%'

sys.sql_dependencies显示对象之间的依赖关系。因此,您可以在更改 TableA 后轻松找到所有依赖于您的对象。可能会给你带来比你需要的更多的结果。

SELECT * FROM sys.sql_dependencies 
WHERE referenced_major_id = object_id('TableA')

无论哪种方式,您都可以加入它sys.objects以获取名称并仅过滤功能(我会包括视图,因为它们也需要在底层对象更改后刷新)'。像这样的东西:

SELECT o.name FROM sys.sql_dependencies d
LEFT JOIN sys.objects o ON d.object_id = o.object_id
WHERE referenced_major_id = object_id('TableA')
AND o.type in ('FN', 'IF', 'TF', 'FS', 'FT', 'V')

B)在你找到你的函数名之后,在了解sp_refreshsqlmodule了刷新依赖对象的过程之后,生成脚本应该不会那么难。

最简单的方法是为每个生成 EXEC,然后复制/粘贴结果并运行它:

SELECT 'EXEC sp_refreshsqlmodule ''' +  o.name + '''' FROM sys.sql_dependencies d
LEFT JOIN sys.objects o ON d.object_id = o.object_id
WHERE referenced_major_id = object_id('TableA')
AND o.type in ('FN', 'IF', 'TF', 'FS', 'FT', 'V')

如果您想要更自动化,请循环、连接单个脚本并运行它。我希望你能处理好。

于 2013-07-29T10:49:47.543 回答