如何检测和获取sql-server tvf函数的底层模式的更改

时间:2013-07-29 09:43:06

标签: sql sql-server-2008

假设我有一个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”脚本,以便所有函数都是使用当前的基础架构更新?

1 个答案:

答案 0 :(得分: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')

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