如何在 SQL Server 数据库中一次删除所有存储过程?
Posted
技术标签:
【中文标题】如何在 SQL Server 数据库中一次删除所有存储过程?【英文标题】:How to drop all stored procedures at once in SQL Server database? 【发布时间】:2010-04-09 20:48:36 【问题描述】:目前我们对脚本文件中的每个存储过程使用单独的删除语句:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MySP]')
AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[MySP]
有没有办法一次性删除它们,或者循环删除它们?
【问题讨论】:
【参考方案1】:我更愿意这样做:
首先通过检查系统目录视图生成要删除的存储过程列表:
SELECT 'DROP PROCEDURE [' + SCHEMA_NAME(p.schema_id) + '].[' + p.NAME + '];'
FROM sys.procedures p
这会在您的 SSMS 输出窗口中生成 DROP PROCEDURE
语句列表。
将该列表复制到新的查询窗口中,并可能对其进行调整/更改,然后执行它
没有杂乱和缓慢的光标,让您能够在实际删除之前检查和仔细检查要删除的过程列表
【讨论】:
我需要这个来部署,所以它必须是自动的。 我真的不得不说光标比复制和粘贴要快。 精湛的答案,节省了我很多时间。 这个非常有用,特别是如果您在不应该添加的地方(如master)意外添加了SP。为您提供一种通过预检查进行清理的简单方法。 更喜欢这种方式!如果您只想删除几个或一半或某些程序子集,也非常方便。如果您添加“order by”,您可以对其进行排序并在删除之前更好地查看。【参考方案2】:类似的东西(发现于Delete All Procedures from a database using a Stored procedure in SQL Server)。
顺便说一句,这似乎是一件非常危险的事情,只是一个想法......
declare @procName varchar(500)
declare cur cursor
for select [name] from sys.objects where type = 'p'
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
exec('drop procedure [' + @procName + ']')
fetch next from cur into @procName
end
close cur
deallocate cur
【讨论】:
你为什么觉得它很危险? 一方面,因为它缺少一个额外的 WHERE 子句:for select [name] from sys.objects where type = 'p' AND is_ms_shipped = 0 顺便说一句,如果你有任何奇怪的东西,请在 proc 名称周围添加 [ ]。 Exec 应该如下所示: exec('drop procedure [' + @procName + ']') 无所畏惧的开发人员喜欢危险的脚本。合十礼。 此脚本缺少架构名称,仅适用于 dbo 对象。【参考方案3】:-
在“对象资源管理器”窗格中,选择“存储过程”文件夹。
按 F7(或从主菜单中选择“查看”>“对象资源管理器详细信息”)。
选择所有过程系统表除外。
按删除按钮并选择确定。
您可以以相同的方式删除表或视图。
【讨论】:
这为我节省了很多时间 :) 我支持这个解决方案,如果是一次性操作,从 GUI 工作会更容易。 兄弟?你救了我的命……谢谢! 我不敢相信这有效,但确实有效。键是 F7 键(没有双关语) 太棒了。我不知道“对象资源管理器详细信息”窗口【参考方案4】:在您的数据库中创建以下存储过程(您要从中删除 sp 的数据库)
然后右键单击该过程 - 单击执行存储过程..
然后点击确定。
create Procedure [dbo].[DeleteAllProcedures]
As
declare @schemaName varchar(500)
declare @procName varchar(500)
declare cur cursor
for select s.Name, p.Name from sys.procedures p
INNER JOIN sys.schemas s ON p.schema_id = s.schema_id
WHERE p.type = 'P' and is_ms_shipped = 0 and p.name not like 'sp[_]%diagram%'
ORDER BY s.Name, p.Name
open cur
fetch next from cur into @schemaName,@procName
while @@fetch_status = 0
begin
if @procName <> 'DeleteAllProcedures'
exec('drop procedure ' + @schemaName + '.' + @procName)
fetch next from cur into @schemaName,@procName
end
close cur
deallocate cur
【讨论】:
最佳答案!也处理模式【参考方案5】:我认为这是最简单的方法:
DECLARE @sql VARCHAR(MAX)='';
SELECT @sql=@sql+'drop procedure ['+name +'];' FROM sys.objects
WHERE type = 'p' AND is_ms_shipped = 0
exec(@sql);
【讨论】:
【参考方案6】:获取数据库中所有存储过程的删除语句 选择“删除程序”+“” + F.NAME + ';' FROM SYS.objects AS F where type='P'
【讨论】:
【参考方案7】:DECLARE @sql VARCHAR(MAX)
SET @sql=''
SELECT @sql=@sql+'drop procedure ['+name +'];' FROM sys.objects
WHERE type = 'p' AND is_ms_shipped = 0
exec(@sql);
【讨论】:
仅代码答案不受欢迎。发布您的代码,几乎没有解释【参考方案8】:试试这个,它对我有用
DECLARE @spname sysname;
DECLARE SPCursor CURSOR FOR
SELECT SCHEMA_NAME(schema_id) + '.' + name
FROM sys.objects
WHERE type = 'P';
OPEN SPCursor;
FETCH NEXT FROM SPCursor INTO @spname;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('DROP PROCEDURE ' + @spname);
FETCH NEXT FROM SPCursor INTO @spname;
END
CLOSE SPCursor;
DEALLOCATE SPCursor;
【讨论】:
【参考方案9】:DECLARE @DeleteProcCommand NVARCHAR(500)
DECLARE Syntax_Cursor CURSOR
FOR
SELECT 'DROP PROCEDURE ' + p.NAME
FROM sys.procedures p
OPEN Syntax_Cursor
FETCH NEXT FROM Syntax_Cursor
INTO @DeleteProcCommand
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC (@DeleteProcCommand)
FETCH NEXT FROM Syntax_Cursor
INTO @DeleteProcCommand
END
CLOSE Syntax_Cursor
DEALLOCATE Syntax_Cursor
【讨论】:
【参考方案10】:试试这个:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'DROP PROCEDURE dbo.'
+ QUOTENAME(name) + ';
' FROM sys.procedures
WHERE name LIKE N'spname%'
AND SCHEMA_NAME(schema_id) = N'dbo';
EXEC sp_executesql @sql;
【讨论】:
【参考方案11】:ANSI 兼容,无光标
DECLARE @SQL national character varying(MAX)
SET @SQL= ''
SELECT @SQL= @SQL+ N'DROP PROCEDURE "' + REPLACE(SPECIFIC_SCHEMA, N'"', N'""') + N'"."' + REPLACE(SPECIFIC_NAME, N'"', N'""') + N'"; '
FROM INFORMATION_SCHEMA.ROUTINES
WHERE (1=1)
AND ROUTINE_TYPE = 'PROCEDURE'
AND ROUTINE_NAME NOT IN
(
'dt_adduserobject'
,'dt_droppropertiesbyid'
,'dt_dropuserobjectbyid'
,'dt_generateansiname'
,'dt_getobjwithprop'
,'dt_getobjwithprop_u'
,'dt_getpropertiesbyid'
,'dt_getpropertiesbyid_u'
,'dt_setpropertybyid'
,'dt_setpropertybyid_u'
,'dt_verstamp006'
,'dt_verstamp007'
,'sp_helpdiagrams'
,'sp_creatediagram'
,'sp_alterdiagram'
,'sp_renamediagram'
,'sp_dropdiagram'
,'sp_helpdiagramdefinition'
,'fn_diagramobjects'
,'sp_upgraddiagrams'
)
ORDER BY SPECIFIC_NAME
-- PRINT @SQL
EXEC(@SQL)
没有光标,不符合ansi:
DECLARE @sql NVARCHAR(MAX) = N''
, @lineFeed NVARCHAR(2) = CHAR(13) + CHAR(10) ;
SELECT @sql = @sql + N'DROP PROCEDURE ' + QUOTENAME(SPECIFIC_SCHEMA) + N'.' + QUOTENAME(SPECIFIC_NAME) + N';' + @lineFeed
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE = 'PROCEDURE'
-- AND SPECIFIC_NAME LIKE 'sp[_]RPT[_]%'
AND ROUTINE_NAME NOT IN
(
SELECT name FROM sys.procedures WHERE is_ms_shipped <> 0
)
ORDER BY SPECIFIC_NAME
-- PRINT @sql
EXECUTE(@sql)
【讨论】:
【参考方案12】:通过混合光标和系统过程,我们将得到一个优化的解决方案,如下:
DECLARE DelAllProcedures CURSOR
FOR
SELECT name AS procedure_name
FROM sys.procedures;
OPEN DelAllProcedures
DECLARE @ProcName VARCHAR(100)
FETCH NEXT
FROM DelAllProcedures
INTO @ProcName
WHILE @@FETCH_STATUS!=-1
BEGIN
DECLARE @command VARCHAR(100)
SET @command=''
SET @command=@command+'DROP PROCEDURE '+@ProcName
--DROP PROCEDURE @ProcName
EXECUTE (@command)
FETCH NEXT
FROM DelAllProcedures
INTO @ProcName
END
CLOSE DelAllProcedures
DEALLOCATE DelAllProcedures
【讨论】:
【参考方案13】:ANSI 兼容,无光标
PRINT ('1.a. Delete stored procedures ' + CONVERT( VARCHAR(19), GETDATE(), 121));
GO
DECLARE @procedure NVARCHAR(max)
DECLARE @n CHAR(1)
SET @n = CHAR(10)
SELECT @procedure = isnull( @procedure + @n, '' ) +
'DROP PROCEDURE [' + schema_name(schema_id) + '].[' + name + ']'
FROM sys.procedures
EXEC sp_executesql @procedure
PRINT ('1.b. Stored procedures deleted ' + CONVERT( VARCHAR(19), GETDATE(), 121));
GO
【讨论】:
【参考方案14】:试试这个:
declare @procName varchar(500)
declare cur cursor
for SELECT 'DROP PROCEDURE [' + SCHEMA_NAME(p.schema_id) + '].[' + p.NAME + ']'
FROM sys.procedures p
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
exec( @procName )
fetch next from cur into @procName
end
close cur
deallocate cur
【讨论】:
以上是关于如何在 SQL Server 数据库中一次删除所有存储过程?的主要内容,如果未能解决你的问题,请参考以下文章