14

多年来,我的数据库有几个连续的维护者,任何可能曾经存在的命名准则都被忽略了。

我想将存储过程重命名为一致的格式。显然我可以从 SQL Server Management Studio 中重命名它们,但这不会更新在后面的网站代码 (C#/ASP.NET) 中进行的调用。

我可以做些什么来确保所有调用都更新为新名称,而不是在代码中搜索每个旧过程名称?Visual Studio 是否有能力重构此类存储过程名称?

注意我不相信我的问题是这个问题的重复,因为后者只是关于在数据库中重命名。

4

13 回答 13

39

您可以分阶段进行更改:

  1. 将存储过程复制到新名称下的新存储过程。
  2. 更改旧的存储过程以调用新的存储过程。
  3. 更改网站中的所有代码后,将日志记录添加到旧存储过程。
  4. 一段时间后,当您没有看到对旧存储过程的任何调用并且您很高兴在网站中找到了所有调用时,您可以删除旧存储过程和日志记录。
于 2010-07-22T12:42:57.793 回答
5

您可以将 SPROC 的“胆量”移动到符合新命名约定的新 SPROC,然后将原始 sproc 保留为委托给新 SPROC 的外壳/包装器。您还可以添加一个“审计”表来跟踪调用旧包装器 SPROC 的时间 - 这样您将知道旧 SPROC 没有依赖关系,并且可以安全地删除旧 SPROC(另外,请确保它是'不仅仅是使用数据库的'你的应用' - 例如跨数据库连接或其他应用程序)

这会带来很小的性能损失,并且不会真正为您带来太多收益(除了能够更轻松地“找到”新的 SPROC 之外)

于 2010-07-22T12:48:48.620 回答
3

您将需要在至少两个方面处理此问题,即应用程序和数据库。可能还有其他区域,您必须小心不要忽视它们。

应用程序

未来项目的良好实践

它有助于抽象出你的存储过程。在我们的应用程序中,我们将所有存储过程封装在一个巨大的类中,我可以这样调用:

Dim SomeData as DataTable = Sprocs.sproc_GetSomeData(5)

这样,代码端就很好并且被封装了。我可以进入 Sprocs.sproc_GetSomeData 并在一个地方调整 sproc 名称,当然我可以右键单击该方法并进行符号重命名以修复解决方案范围内的方法调用。

没有抽象

如果没有这种抽象,您可以只对存储过程名称执行 Find In Files (Cntl+Shift+F),然后如果结果看起来正确,打开文件并查找/替换所有出现。

Sql 服务器

不要信任视图依赖项

在 SQL 服务器端,理论上在 MSSMS 2008 中,您可以右键单击存储过程并选择查看依赖项。这应该会向您显示数据库中使用 sproc 的所有位置的列表,但是我对此功能的信心非常低。在 SQL 2008 中可能会更好,但在以前的版本中肯定有问题。

View Dependencies 伤害了我,这需要时间来治愈。:)

包起来!

你最终不得不保留旧的 sproc 一段时间。这就是为什么重命名 sprocs 是一个这样的项目的主要原因 - 最终可能需要一个月的时间才能完成。

首先用一些简单的 TSQL 替换它的内容,该 TSQL 使用相同的参数调用新的 sproc,并编写一些日志记录,以便一段时间后,您可以判断旧的 sproc 是否实际上未使用。

最后,当您确定旧的 sproc 未被使用时,将其删除。

别的地方?

可能还有很多其他领域。报告服务浮现在脑海中。SSIS 包。使用保留旧存储区并重新路由到新存储区的技术(如上所述)将帮助您知道是否错过了任何内容,但它不会告诉您错过了什么。这会导致很多痛苦!

祝你好运!

于 2010-07-22T12:41:58.870 回答
2

缺少测试应用程序中的每条路径以确保对数据库和相关存储过程的任何调用都已更新......不。

使用全局搜索和替换(但查看每个建议的替换)来尽量避免丢失任何实例。如果您的应用程序结构良好,那么每个存储过程实际上应该只有 1 个位置被调用。

于 2010-07-22T12:35:52.933 回答
2

至于更改您的应用程序,我将所有存储的过程作为 web.config 文件中的设置,因此所有名称都在一个地方,并且可以随时更改以匹配对数据库的更改。

当应用程序需要调用存储过程时,名称由 web.config 确定。

这使得管理应用程序可能对数据库服务层进行的所有潜在调用变得更加容易。

于 2010-07-22T12:45:15.893 回答
2

恐怕通过您的源代码和其他数据库对象进行搜索会有点乏味。

不要忘记 SSIS 包、SQL 代理作业、报告服务 rdl 以及您的主要应用程序代码。

如果您有一个支持使用正则表达式搜索文件的工具,您可以使用正则表达式spProc1|spProc2同时在源代码中搜索所有对象名称(我过去曾为此使用过 RegexBuddy)

如果您只想涵盖您可能错过了奇怪的可能性,您可以将所有以前的存储过程留在一个月后,让他们记录自定义 SQL 跟踪事件以及APP_NAME(), SUSER_NAME()您认为有用的任何其他信息,然后让它调用重命名的版本。然后设置跟踪监视此事件。

于 2010-07-22T12:49:18.900 回答
1

如果您使用与 DB、存储过程等的连接,您应该创建一个服务类来委派这些方法。

这样,当您的数据库、SP 等中的某些内容发生更改时,您只需更新您的服务类,并且所有内容都受到保护,不会被破坏。

VS 有一些工具可以管理更改名称,例如重构和 resharper

于 2010-07-22T12:36:45.820 回答
1

我这样做了,我严重依赖源代码中的全局搜索来查找存储过程名称和 SQL 挖掘器来查找调用 sql 过程的 sql 过程。

http://www.sqldigger.com/

SQL Server(从 SQL 2000 开始)对其自身的依赖关系了解甚少,因此只能搜索脚本文本以查找依赖关系,这可能是其他存储的过程或动态 sql 的子字符串。

于 2010-07-22T12:48:06.820 回答
1
  1. 我将使用以下内容获取对过程的引用列表,因为 SSMS 依赖项不会获取数据库外部的动态 SQL 引用或引用。

    SELECT OBJECT_NAME(m.object_id), m.*
      FROM SYS.SQL_MODULES m
     WHERE m.definition LIKE N'%my_sproc_name%'
    
    • SQL 需要在每个可能有引用的数据库中运行。
    • syscomments 和 INFORMATION_SCHEMA.routines 有 nvarchar(4000) 列。因此,如果在位置 3998 处使用了“mySprocName”,则不会找到它。syscomments 确实有多行,但 ROUTINES 会截断。 如果您不同意,请与 gbn 讨论
  2. 基于该依赖关系列表,我将创建新的存储过程,启动基础存储过程 - 那些具有最少依赖关系的存储过程。但我不介意创建存储过程,在名称前加上“sp_”
  3. 验证基础程序与现有程序的工作方式相同
  4. 移动到存储过程的下一级 - 根据需要重复步骤 1-3,直到处理完最高级别的过程。
  5. 测试应用程序使用到新过程的切换 - 不要等到所有过程都更新后才能测试与应用程序代码的交互。不需要对每个存储过程都执行此操作,但等待批量执行此操作也不是一个好方法。

并行开发也有风险:

  • 对现有代码的任何更改也需要应用于新代码。如果可能的话,在开发被冻结的领域工作或使用错误修复作为迁移到新代码的机会,而不是在两个地方应用补丁(同时也尽量减少过渡的停机时间)。
于 2010-07-22T16:27:10.320 回答
0

使用FileSeek之类的实用程序来搜索项目文件夹中每个文件中的内容。不要相信 Windows 搜索 - 它速度慢且对用户不友好。

因此,如果您有一个名为OldSprocOne的存储过程并希望将其重命名为SP_NewONe,请搜索所有出现的 OldSprocOne ,然后搜索所有出现的 OldSprocOne以查看该名称是否尚未在其他地方使用并且不会导致问题。然后重命名代码中的每一个出现。

对于较大的系统,这可能非常耗时且重复。

于 2010-07-22T13:11:09.747 回答
0

我会更关心忽略过程的名称并用 Enterprise Library Data Access Block 5 替换您的旧 DAL

Enterprise Library 5 DAAB 中的数据库访问器 - Database.ExecuteSprocAccessor

拥有类似的代码

 public Contact FetchById(int id)
 {
  return _database.ExecuteSprocAccessor<Contact>
   ("FetchContactById", id).SingleOrDefault();
 }

与具有一致名称的存储过程相比,它的价值至少要高出十亿倍,尤其是如果当前代码绕过 DataTables 或 DataSets ::shudders::

于 2010-07-22T14:06:50.210 回答
0

我完全赞成重构任何类型的代码。

您真正需要的是一种缓慢且增量地重命名存储过程的方法。
我当然不会进行全局查找和替换。

相反,当您识别小块功能并了解 proc 之间的关系时,您可以重新考虑小块。

然而,这个过程的基础是对数据库的源代码控制。
如果您没有像普通代码一样管理对数据库的更改,您将遇到严重的麻烦。

看看 DBSourceTools。http://dbsourcetools.codeplex.com
它专门设计用于帮助开发人员将他们的数据库置于源代码控制之下。

在重构之前,您需要一种可重复的方法将数据库恢复到特定状态。
然后以受控方式重新应用重构的更改。

一旦你接受了这种心态,这个庞大且容易出错的任务就会变得简单。

于 2010-07-23T01:49:10.563 回答
0

这是假设您使用 SQL Server 2005 或更高版本。我之前使用的一个选项是重命名旧数据库对象并使用旧名称创建 SQL Server 同义词。这将允许您将对象更新为您选择的任何约定,并在您使用它们时替换代码、SSIS 包等中的引用。然后,您可以集中精力逐步更新代码中的引用,而不是您选择的维护版本(而不是一次全部破坏)。当您觉得您已找到所有参考资料时,您可以在代码进入 QA 时删除同义词。

于 2010-07-23T02:30:04.587 回答