【发布时间】:2018-01-05 16:42:09
【问题描述】:
我的生产环境中有一个存储过程,最初是由没有足够时间正确设计它的人编写的。它是通过链接服务器连接编写的 9 个或更多连接到数据库的。
存储过程需要一个多小时才能运行。大约一年半前,我重新设计了它(设计它?)以更有效地访问数据,现在存储过程只在链接服务器上进行 2 次不同的调用。进行这些更改后,运行时间降至不到 5 分钟。
大约 6 个月后(以及产品发布后的第二天),存储过程性能恢复到运行一个多小时。当我查看存储过程(右键单击,修改)时,代码已经恢复了旧的糟糕代码。
没有人有权运行ALTER PROCEDURE 会承认更改了它,所以我做了任何理性信任的 DBA 都会做的事情 - 我再次修复它并在生产数据库上放置 DDL 审计触发器以跟踪任何和所有生产中的 DDL 更改。
大约 6 个月后,糟糕的代码在产品发布后的第二天又回来了。检查 DDL 审计表显示没有触及存储过程。我修复了存储过程,修复事件显示在 DDL 审计表中。 W.T.H.??
我们通过使用 Visual Studio 在 beta 和 prod 之间进行架构比较来构建我们的数据库发布脚本,然后生成一个脚本。生成的部分脚本是几个
EXECUTE sp_refreshsqlmodule N'[dbo].[db object here]';
来电。对于接下来的几个版本,我确保不执行有问题的存储过程的sp_refreshsqlmodule - 我们没有问题。然后我要发布一个版本,备份 DBA 没有删除 sp_refreshsqlmodule 调用 - 错误代码返回,没有 DDL 审计记录。
我们的生产服务器已经用正确的代码硬启动了几次。 sp_refreshsqlmodule 在哪里/如何/做什么来获取存储过程的旧副本并将其覆盖在好的副本上?如何强制存储过程的好版本进入这个神奇的藏身之地?
【问题讨论】:
-
我已经能够在 SQL 2008 R2 上复制此错误 - 撰写本文时的最新补丁 10.50.6560.0 我还确认它在 SQL Server 2012 SP4 上运行良好,尽管我已经无法确切知道何时修复此问题。结果是避免在 2008 R2 上使用 sp_refreshsqlmodule。
标签: stored-procedures sql-server-2008-r2