从数据库项目中批量删除数据库对象
Posted
技术标签:
【中文标题】从数据库项目中批量删除数据库对象【英文标题】:Bulk Remove Database Objects From Database Project 【发布时间】:2017-06-02 19:53:48 【问题描述】:我目前正在维护一个超过 17 年的 SQL Server 数据库,其中包含大量未使用和过时的工件。
在过去的几个月里,我们一直在对数据库进行概要分析,以确定 1800 多个存储过程中的哪些实际正在被使用,哪些是我们可以安全删除的。截至目前,我们计划删除大约 1300 个列表。
此数据库也在我们的 SQL Server 数据库项目中的源代码控制下签入。
现在,我想做的是生成一个脚本来删除 1300 个过程,并首先将该脚本应用于数据库项目,然后再将该脚本应用于我们的开发环境。但我似乎无法找到通过脚本更新项目的方法。
我尝试过执行Import
> Script
并使用DROP PROCEDURE
命令导入.sql
文件,但它会引发以下错误,同时不会从项目中删除该过程:
在您提供给导入操作的脚本中,一个或多个语句没有被完全理解。这些语句已移至 ScriptsIgnoredOnImport.sql 文件。查看文件内容以获取更多信息。
测试的文件内容如下:
Drop Procedure spProcedureName;
我可以浏览项目并逐个删除每个程序...但是要删除的有1300多个...
有没有办法对数据库项目进行批量更新(通过脚本或其他方式)以删除多个数据库对象?
其他信息:
从项目中创建一个 shell 数据库并对其进行更新将证明与手动删除 1,300 个存储过程一样多。这是因为我们计划删除的许多存储过程包含对表、视图、函数、OPENROWSET
连接和其他过程的过时/无效引用。因此,部署脚本会失败,如果不修改脚本中的各个无效对象,就无法创建 shell 数据库。
获取当前数据库的备份/恢复也不是一个可行的解决方案,因为当前数据库的大小略高于 3 TB。
由于上述限制,我只是在寻找一种可以直接应用于数据库项目而不依赖于辅助物理数据库的解决方案。
【问题讨论】:
最简单的是DROP PROCEDURE command listing SPs separated by a comma
Sample Code
否则您可以将 SP 的名称推送到临时表中,然后使用 query 循环它
@Joby 我的问题不是如何从数据库中删除过程,而是如何从数据库项目中批量删除过程。
@Siyual 如何检索未使用的 1300 SP
@AlfaizAhmed 这有点太复杂,无法在评论中详细介绍,但基本上,我编写了一个服务,定期检查最近使用的存储过程统计信息并在几个月内编译这些结果.
【参考方案1】:
-
将项目部署到新数据库 (DB_Temp)
通过 TSQL 删除旧的存储过程
创建一个新的数据库项目并从 DB_Temp 导入数据库架构。
更新/检查项目设置,包括发布设置以删除不在项目中的 SP。
将项目部署到 DEV 和 Test 环境,并进行测试。
删除旧项目
删除 DB_Temp
更新:
另一种方式:
-
将项目部署到新数据库 (DB_Temp)
通过 TSQL 删除旧的存储过程
在 VS 中,运行 Tools-->SQL Server-->Schema Comparison (Source: DB_Temp, Target: your project)
按“更新”从项目中删除旧的 SP
将项目部署到 DEV 和 Test 环境,并进行测试。
删除 DB_Temp
【讨论】:
这是一个可能的解决方案,但如果可能的话,我想避免这条路线。我更喜欢可以直接应用于数据库项目的解决方案,无需依赖物理数据库。 我不确定有没有比这更好的方法。即使出现故障或类似地创建一些 shell DB,您也应该能够设置发布选项以继续进行。从中删除对象,然后比较并从项目中删除。如果您的数据库项目构建,您可以针对 (localdb) 数据库实例执行此操作以删除对象,然后将 that 与您的项目进行比较以删除。 Siyual,根据 Peter 的建议查看更新的答案 - 这种方式步骤更少且更简单,但您仍然需要创建一个物理(临时)数据库。还有一种编程方式可以从项目中删除对象 - 请参阅另一个答案。 @PeterSchott 如果遇到错误可以在哪里继续?我在任何地方都没有看到这个选项。 @Anton 不幸的是,这仍然不起作用。对于我的特定数据库来说,这可能是一个边缘案例,但即使它构建了,由于对象无效,它也无法部署。我没有看到继续部署遇到错误的方法,但是如果您知道该设置在哪里,则此解决方案将起作用。【参考方案2】:要以编程方式从项目中删除对象,您可以使用 EnvDTE.ProjectItem 类的 Remove() 方法。
https://msdn.microsoft.com/en-us/library/envdte.projectitem.remove.aspx
有很多VS扩展可以运行EnvDTE命令,像这样:https://vlasovstudio.com/visual-commander/index.html
或者你可以使用包管理控制台(工具--> NuGet包管理器-->包管理控制台)
步骤 1。将 SP 列表分配给变量:
$IncludeList = "SP1.sql", "SP2.sql"
步骤 2。如果 SP 在列表中,则从项目中删除它。
如果您的 SP 项目路径类似于“Database2\dbo\Stored Procedures\”,则类似于:
$DTE.Solution.Projects | ForEach if ($.Name -eq "Database2") $.ProjectItems | ForEach if ($.Name -eq "dbo") $.ProjectItems | ForEach if ($.Name -eq "存储过程") $.ProjectItems | ForEach if ($IncludeList -contains $.Name) $.Remove()
【讨论】:
以上是关于从数据库项目中批量删除数据库对象的主要内容,如果未能解决你的问题,请参考以下文章