sql-server - 重新编译存储过程?

标签 sql-server sql-server-2005 sql-server-2008

有没有办法重新编译或至少“检查编译”存储过程?有时我们会更改架构 - 添加或删除一列等。并尽最大努力识别受影响的过程,只是被我们错过的一个咬伤,下次运行时会吐出来。 SQLServer 2k5 或 2k8。

最佳答案

我将您的问题理解为“当我进行模式更改时,我想验证所有过程它们仍然可以使用新模式正确执行”。 IE。如果您删除在过程中的 SELECT 中引用的列,那么您希望将其标记为需要更改。所以具体来说,我不理解你的问题是“我希望程序在下次执行时重新编译”,因为该工作由引擎为你处理,它将检测与任何模式更改相关的元数据版本更改并丢弃现有的缓存的执行计划。

我的第一个观察是,您在问题中描述的内容通常是TEST 的工作,您应该在部署过程中有一个 QA 步骤来验证新的“构建”。您可能拥有的最佳解决方案是实现一组最小的单元测试,至少在测试部署中迭代所有存储过程并验证每个存储过程的执行是否正确。这几乎可以消除所有的意外,至少可以消除伤害的地方(在生产中或在客户现场)。

您的下一个最佳选择是依靠您的开发工具来跟踪这些依赖关系。 Visual Studio Database 2008 Database Edition提供开箱即用的此类功能,它将负责验证您在架构中所做的任何更改。

最后,您的最后一个选择是执行类似于 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

然后您可以运行依赖的“模块”并重新创建它们(即删除它们并运行“定义”中的代码)。请注意,“模块”比存储过程更通用,还涵盖 View 、触发器、函数、规则、默认值和复制过滤器。加密的“模块”将没有定义可用的定义,为了绝对正确,您还必须考虑 sys.sql_modules 中捕获的各种设置(ansi null、模式绑定(bind)、执行子句等)。

如果您使用动态 SQL,则无法验证。它不会被 sys.sql_dependencies 捕获,也不会通过“重新创建”模块来验证。

总体而言,我认为您最好的选择是实现单元测试验证。

关于sql-server - 重新编译存储过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1060512/

相关文章:

c# - 无法在 Visual Studio 2012 Professional 中导入数据库

sql-server - 将日期时间格式中的 NULL 值更改为空字符串

c# - 插入语句组合逻辑

sql - 乱七八糟的SQL语句

SQL Server : COALESCE causing excessive runtime

sql-server - 从数据库中的 ParentID 创建嵌套的 <ul> 树结构

sql - MSSQL 存储过程选择所有列

SQL Server 查询性能 - 聚集索引查找

where 条件中的 SQL IN 子句导致大数据性能问题

c# - SQL 中应该如何表示时间段?