Sql server 重新编译存储过程?

Sql server 重新编译存储过程?,sql-server,sql-server-2005,sql-server-2008,Sql Server,Sql Server 2005,Sql Server 2008,是否有一种方法可以重新编译或至少“检查编译”整个存储过程?有时,我们会对模式进行更改—添加或删除列等,并尽最大努力识别受影响的进程,这些进程只会被我们错过的进程咬到,而下一个运行时会呕吐。SQLServer2K5或2k8。从sysobjects获取列表后,只需遍历它们,然后运行: 下面是一个显示示例脚本的链接: 您可以使用DBCC FREEPROCCACHE 如果在更改表和中断存储过程时遇到问题,请尝试sp_,具体取决于: 此外,您还可以使用sp_重新编译: 但这只会在下次运行相关存储过程时将其

是否有一种方法可以重新编译或至少“检查编译”整个存储过程?有时,我们会对模式进行更改—添加或删除列等,并尽最大努力识别受影响的进程,这些进程只会被我们错过的进程咬到,而下一个运行时会呕吐。SQLServer2K5或2k8。

从sysobjects获取列表后,只需遍历它们,然后运行:

下面是一个显示示例脚本的链接:

您可以使用DBCC FREEPROCCACHE


如果在更改表和中断存储过程时遇到问题,请尝试sp_,具体取决于:

此外,您还可以使用sp_重新编译:

但这只会在下次运行相关存储过程时将其标记为重新编译


您可以使用management studio或源代码管理将所有过程的连接创建脚本生成到单个文件中,然后运行该脚本。

我将您的问题理解为“当我更改架构时,我希望验证它们仍然使用新架构正确执行的所有过程”。例如,如果您删除了在过程中的SELECT中引用的列,那么您希望在需要更改时对其进行标记。因此,我不认为您的问题是“我希望在下次执行时重新编译该过程”,因为该作业由引擎负责,引擎将检测与任何架构更改相关的元数据版本更改,并丢弃现有缓存的执行计划

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

您的下一个最佳选择是依靠您的开发工具来跟踪这些依赖关系。提供了这种开箱即用的功能,它将负责验证您在模式中所做的任何更改

最后,您的最后一个选择是做一些类似于KM建议的事情:根据修改的对象自动迭代所有过程,根据依赖的对象自动迭代,依此类推。仅仅将过程标记为重新编译是不够的,您真正需要的是运行ALTER过程来触发对其文本的解析和对模式的验证。t-SQL与您通常的语言编译/执行周期有点不同,只有当过程实际执行时,“编译”本身才会发生。您可以通过迭代来查找更改对象的所有依赖项,还可以从以下位置查找依赖项的“模块定义”:

然后,您可以运行相关的“模块”并重新创建它们,即删除它们并在“定义”中运行代码。请注意,“模块”比存储过程更通用,还包括视图、触发器、函数、规则、默认值和复制筛选器。加密的“模块”将没有可用的定义,为了绝对正确,您还必须考虑sys.sql_模块ansi NULL、架构绑定、执行为子句等中捕获的各种设置

如果使用的是动态SQL,则无法验证。它不会被sys.sql_依赖项捕获,也不会通过“重新创建”模块进行验证


总的来说,我认为您最好的选择是实施单元测试验证。

我知道您的意思,并且在许多情况下,我都意识到您的需要。你可以看看


祝您好运,Ron

无论何时,只要您进行了架构更改,从而使SQL server的执行计划无效,SQL server都会将该sp标记为重新编译。你怎么把它关掉了!!?不,比这更令人悲伤。TDD将帮助我们——例如,这些存储过程依赖于我们删除的列,在执行该过程之前,我们不会“发现”这一点。使用sp_recompile tablename更容易,因为它将标记引用该表的所有过程以进行重新编译。但是,这对OP不起作用,因为sp_重新编译只标记重新编译的过程。它们实际上是在下次运行时编译的,这与OPs更改在运行时吐出的时间相同。MSDN说,sp_重新编译会导致存储过程和触发器在下次运行时重新编译。,因此,在调用proc之前,这不会发现错误。这是一个很好的答案,但不幸的是,它只适用于同一数据库中的数据库对象。如果来自另一个数据库的某些sql代码引用了它,那么sp_将不会列出该数据库。
sp_depends [ @objname = ] '<object>' 

<object> ::=
{
    [ database_name. [ schema_name ] . | schema_name.
        object_name
}
EXECUTE sp_depends  YourChangedTableName
EXEC sp_recompile YourChangedTable
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