n8w*_*wrl 2 sql-server sql-server-2005 sql-server-2008
有没有办法重新编译或至少"检查编译"存储过程?有时我们会进行架构更改 - 添加或删除列等.并尽最大努力识别受影响的触发器,但只会被我们错过的触发器咬住,这会在下一次运行时发挥作用.SQLServer 2k5或2k8.
我理解你的问题是"当我进行架构更改时,我想验证它们仍然使用新架构正确执行的所有过程".IE浏览器.如果删除过程中SELECT中引用的列,则需要将其标记为需要更改.所以具体来说,我不明白你的问题是"我希望程序在下次执行时重新编译",因为引擎会为你完成这项工作,它将检测与任何模式更改相关的元数据版本更改并丢弃现有的缓存执行计划.
我的第一个观察是你在问题中描述的内容通常是测试的工作,你应该在部署过程中有一个QA步骤来验证新的"构建".您可以拥有的最佳解决方案是在测试部署中实现一组最小的单元测试,这些测试至少会遍历所有存储过程并验证每个存储过程的执行是否正确.这几乎可以消除所有的惊喜,至少在它受到伤害的地方消除它们(在生产中或在客户现场).
您的下一个最佳选择是依靠您的开发工具来跟踪这些依赖关系.在Visual Studio的数据库2008年数据库版提供了这样的功能外的盒子,它会带你验证的架构进行任何改变的照顾.
最后你的最后一个选择是做一些类似于KM建议的事情:根据修改后的对象自动迭代所有程序(以及所有依赖于依赖程序的程序,依此类推等等).标记重新编译的过程是不够的,你真正需要的是运行ALTER PROCEDURE来触发其文本的解析和模式的验证(T-SQL与你的通常语言有些不同)编译/执行循环,'编译'本身只在程序实际执行时才会发生).您可以首先遍历sys.sql_dependencies
查找已更改对象的所有依赖项,还可以从以下位置找到依赖项的"模块定义" sys.sql_modules
:
with cte_dep as (
select object_id
from sys.sql_dependencies
where referenced_major_id = object_id('<your altered object name>')
union all
select d.object_id
from sys.sql_dependencies d
join cte_dep r on d.referenced_major_id = r.object_id
)
, cte_distinct as (
select distinct object_id
from cte_dep)
select object_name(c.object_id)
, c.object_id
, m.definition
from cte_distinct c
join sys.sql_modules m on c.object_id = m.object_id
Run Code Online (Sandbox Code Playgroud)
然后,您可以运行依赖的"模块"并重新创建它们(即删除它们并在"定义"中运行代码).请注意,"模块"比存储过程更通用,还包括视图,触发器,函数,规则,默认值和复制过滤器.加密的"模块"将无法定义可用的定义,并且绝对正确您还必须考虑sys.sql_modules
(ansi nulls,schema binding,execute as clauses等)中捕获的各种设置.
如果使用ynamic SQL,则无法验证.它不会被捕获sys.sql_dependencies
,也不会通过"重新创建"模块来验证.
总的来说,我认为你最好的选择是实施单元测试验证.
归档时间: |
|
查看次数: |
5170 次 |
最近记录: |