假设我有一个inline-tvf函数(假设名称:cfn_test),定义如下:
SELECT * FROM TableA;
现在,在创建时,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”脚本,以便所有函数都是使用当前的基础架构更新?
答案 0 :(得分:1)
A)您可以使用系统视图 - sys.sql_modules
或sys.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')
如果您想要更多自动化,循环,连接单个脚本并运行它。我希望你能处理它。