SQL Remove All Constraints Azure Friendly - sql

I'm doing some DB Admin with an Azure database and I need to perform queries like removing all constraints in the database.
sp_MSForEachTable is not available when working with Azure databases, so I'm working on a different way to do it.
I found a snippet that drops all tables here: http://edspencer.me.uk/2013/02/25/drop-all-tables-in-a-sql-server-database-azure-friendly/ and tried modifying it to remove all constraints like I need to and came up with this result:
while(exists(select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME != '__MigrationHistory'))
begin
PRINT ('Disabling' + TABLE_NAME)
declare #constraintOff nvarchar(2000)
SELECT TOP 1 #constraintOff=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] ' + 'NOCHECK CONSTRAINT all')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME != '__MigrationHistory'
exec (#constraintOff)
PRINT #constraintOff
end
It repeatedly tries to operate on the first item in the database, which would work fine if you were dropping everything but I need to loop through each table and disable its constraint like sp_MSForEachTable does.
Any tips? I've seen a few things here and there that claim to do this, but they're usually two or three page long scripts that do a lot of other stuff and they make my brain hurt.
UPDATE
still working on that query, it seems like something to this end might work better but still no dice:
declare #constraintOff nvarchar(2000)
SELECT #constraintOff=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] ' + 'NOCHECK CONSTRAINT all')
FROM INFORMATION_SCHEMA.TABLES
exec (#constraintOff)
PRINT #constraintOff
This one still only operates on one table, but at least it's not an infinite loop :)

While this link is for Amazon RDS, it does provide specific code to disable constraints without sp_MSForEachTable
Importing and Exporting SQL Server Data
-- Manually specify database name - a safeguard in case you paste this into the wrong SSMS window.
USE [staging]
-- Change this line if you want to enable (1) or disable constraints:
DECLARE #enable_constraints bit = 0
--Don't change anything below this line.
DECLARE #schema_name SYSNAME
DECLARE #table_name SYSNAME
DECLARE table_cursor CURSOR FOR
SELECT
schemas.name,
tables.name
FROM
sys.tables
INNER JOIN sys.schemas ON tables.schema_id = schemas.schema_id
OPEN table_cursor
FETCH NEXT FROM table_cursor INTO #schema_name, #table_name
DECLARE #cmd varchar(200)
WHILE ##FETCH_STATUS = 0
BEGIN
SET #cmd = 'ALTER TABLE ' + QUOTENAME(#schema_name) + '.' + QUOTENAME(#table_name) + ' '
SET #cmd = #cmd + (CASE WHEN #enable_constraints = 1 THEN 'CHECK' ELSE 'NOCHECK' END) + ' CONSTRAINT ALL'
PRINT #cmd
EXEC( #cmd )
FETCH NEXT FROM table_cursor INTO #schema_name, #table_name
END
CLOSE table_cursor
DEALLOCATE table_cursor

Extended the script to deal with tables in different schemas, also corrected the above script that is not disabling checks:
-- DISABLE ALL CONSTRAINTS
DECLARE #table_name SYSNAME;
DECLARE #schema_name SYSNAME;
DECLARE #cmd NVARCHAR(MAX);
DECLARE table_cursor CURSOR FOR
SELECT s.name, t.name
FROM sys.tables t
join sys.schemas s on t.schema_id = s.schema_id
OPEN table_cursor;
FETCH NEXT FROM table_cursor INTO #schema_name, #table_name;
WHILE ##FETCH_STATUS = 0 BEGIN
SELECT #cmd = 'ALTER TABLE '+QUOTENAME(#schema_name)+'.'+QUOTENAME(#table_name)+' NOCHECK CONSTRAINT ALL';
EXEC (#cmd);
FETCH NEXT FROM table_cursor INTO #schema_name, #table_name;
END
CLOSE table_cursor;
DEALLOCATE table_cursor;
-- enable all constraints
DECLARE table_cursor CURSOR FOR
SELECT s.name, t.name
FROM sys.tables t
join sys.schemas s on t.schema_id = s.schema_id
OPEN table_cursor;
FETCH NEXT FROM table_cursor INTO #schema_name, #table_name;
WHILE ##FETCH_STATUS = 0 BEGIN
SELECT #cmd = 'ALTER TABLE '+QUOTENAME(#schema_name)+'.'+QUOTENAME(#table_name)+' CHECK CONSTRAINT ALL';
EXEC (#cmd);
FETCH NEXT FROM table_cursor INTO #schema_name, #table_name;
END
CLOSE table_cursor;
DEALLOCATE table_cursor;

Related

Stored procedure to drop the column in SQL Server

I created many tables and I have noticed that I have created one useless column in all the tables. I want to create a stored procedure which will drop one specific column and can be useful in all the column.
I created this stored procedure but I'm getting an error. Help me please
You cannot parametrize table and column names with parameters - those are only valid for values - not for object names.
If this is a one-time operation, the simplest option would be to generate the ALTER TABLE ... DROP COLUMN ... statements in SSMS using this code:
SELECT
'ALTER TABLE ' + SCHEMA_NAME(t.schema_id) + '.' + t.Name +
' DROP COLUMN Phone;'
FROM
sys.tables t
and then execute this code in SSMS; the output from it is a list of statement which you can then copy & paste to a new SSMS window and execute.
If you really want to do this as a stored procedure, you can apply the same basic idea - and then just use code (a cursor) to iterate over the commands being generated, and executing them - something like this:
CREATE PROCEDURE dbo.DropColumnFromAllTables (#ColumnName NVARCHAR(100))
AS
BEGIN
DECLARE #SchemaName sysname, #TableName sysname
-- define cursor over all tables which contain this column in question
DECLARE DropCursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT
SchemaName = s.Name,
TableName = t.Name
FROM
sys.tables t
INNER JOIN
sys.schemas s ON t.schema_id = s.schema_id
WHERE
EXISTS (SELECT * FROM sys.columns c
WHERE c.object_id = t.object_id
AND c.Name = #ColumnName);
-- open cursor and start iterating over the tables found
OPEN DropCursor
FETCH NEXT FROM DropCursor INTO #SchemaName, #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #Stmt NVARCHAR(1000)
-- generate the SQL statement
SET #Stmt = N'ALTER TABLE [' + #SchemaName + '].[' + #TableName + '] DROP COLUMN [' + #ColumnName + ']';
-- execute that SQL statement
EXEC sp_executeSql #Stmt
FETCH NEXT FROM DropCursor INTO #SchemaName, #TableName
END
CLOSE DropCursor
DEALLOCATE DropCursor
END
This procedure should work.
It loops through all cols and then deletes the column where sum(col) is zero.
Take a Backup of the Table
alter procedure deletecolumnsifzero #tablename varchar(1000)
as
set nocount on
declare #n int
declare #sql nvarchar(1000)
declare #sum_cols nvarchar(1000)
declare #c_id nvarchar(100)
set #n = 0
declare c1 cursor for
select column_name from information_schema.columns
where
table_name like #tablename
--Cursor Starts
open c1
fetch next from c1
into #c_id
while ##fetch_status = 0
begin
set #sql=''
set #sql='select #sum_cols = sum('+#c_id+') from ['+#tablename+']'
exec sp_Executesql #sql,N'#sum_cols int out,#tablename nvarchar(100)',#sum_cols out,#tablename
if(#sum_cols = 0)
begin
set #n=#n+1
set #sql=''
set #sql= #sql+'alter table ['+#tablename+'] drop column ['+#c_id+']'
exec sp_executesql #sql
end
fetch next from c1
into #c_id
end
close c1
deallocate c1

SQL Server - changing definition of column that appears in multi tables

many of tables in my DB have a Boolean column 'IsDeleted'.
I need to alter the column in all tables, that the default value will be zero, and then update all old records with value null, to be with value zero.
There is a way to do it beside writing a script for every table?
Thanks,
This would be a good starting point to generate the CReate, Update and Rename scripts required. Advisory: TEST ON BACKUP OF DATABASE FIRST.
select
'ALTER TABLE dbo.' + O.Name + ' ADD IsDeletedNew bit default 0;
UPDATE dbo.' + O.Name + ' SET IsDeletedNew = 1 WHERE IsDeleted = 1;
UPDATE dbo.' + O.Name + ' SET IsDeletedNew = 0 WHERE IsDeleted = 0 OR IsDeleted IS NULL;
ALTER TABLE dbo.' + O.Name + ' DROP COLUMN IsDeleted;
EXECUTE sp_rename N''dbo.' + O.Name + '.IsDeletedNew'', N''Tmp_IsDeleted_1'', ''COLUMN''
EXECUTE sp_rename N''dbo.' + O.Name + '.Tmp_IsDeleted_1'', N''IsDeleted'', ''COLUMN'' '
from syscolumns C
Inner join sysobjects o on C.ID = O.ID
where c.name = 'IsDeleted'
First, I can set a default value for a boolean filed. It worked for me.
ALTER TABLE [dbo].<TableName> ADD DEFAULT 0 FOR IsDeleted
This is my script that sets default value for every 'IsDeleted' field that doesn't have a defualt value. It worked for me.
DECLARE #NAME VARCHAR(100)
DECLARE #SQL NVARCHAR(300)
DECLARE CUR CURSOR
FOR
SELECT t.name AS 'TableName'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name = 'IsDeleted'
AND (SELECT object_definition(default_object_id) AS definition
FROM sys.columns
WHERE name ='IsDeleted'
AND object_id = object_id(t.name)) is null
OPEN CUR
FETCH NEXT FROM CUR INTO #NAME
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'ALTER TABLE [dbo].'+#NAME+' ADD DEFAULT 0 FOR IsDeleted'
--PRINT #SQL -- will print all the update scripts
EXEC Sp_executesql #SQL
FETCH NEXT FROM CUR INTO #NAME
END
CLOSE CUR
DEALLOCATE CUR
With so many tables, do the alter using dynamic SQL
declare #tab_name varchar(120)
declare #the_sql varchar(1000)
declare MyCursor cursor
for
select distinct table_name
from INFORMATION_SCHEMA.COLUMNS
where column_name = 'IsNumeric'
open MyCursor
fetch next from MyCursor into #tab_name
while ##fetchstatus = 0
begin
set #the_sql = 'alter table ' + #tab_name + ' add NewNumeric bit default 0'
execute (#the_sql)
fetch next from MyCursor into #tab_name
end
close MyCursor
deallocate MyCursor
rinse and repeat to updatethe values, delete the old column and then update the new column

Find all database tables where a common column is set to a value

All database tables have a UserId field of [uniqueidentifier] type.
I need to query the entire database and get the list of tables that have UserId set to a specific value.
Right now I achieved this by using cursor and the results are horrible and are difficult to read. How can I improve this query to retrieve back a clear list with tables and count of record that have UserId set to a specific value, instead of using this:
DECLARE #TableName VARCHAR(127);
DECLARE #Value VARCHAR(512);
DECLARE #SqlCommand varchar(1000)
--Use cursor to loop through database tables that contain UserId column
DECLARE db_cursor CURSOR FOR
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name = 'UserId';
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO #TableName;
WHILE ##FETCH_STATUS = 0
BEGIN
--Check if the next table has any UserId matching the where clause
EXEC('SELECT COUNT(UserId) , ''' + #TableName + ''' FROM ' + #TableName + ' WHERE UserId = ''FF13ACCA-022C-4296-AB3D-A35700E35BB3''');
FETCH NEXT FROM db_cursor INTO #TableName;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;
You made all the difficult part, just put the value in a temp table and select them once you've finished.
DECLARE #TableName VARCHAR(127);
DECLARE #Value VARCHAR(512);
DECLARE #SqlCommand varchar(1000)
--Creta temp table
CREATE TABLE #Results (Number int, Tablename sysname)
--Use cursor to loop through database tables that contain UserId column
DECLARE db_cursor CURSOR FOR
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name = 'UserId';
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO #TableName;
WHILE ##FETCH_STATUS = 0
BEGIN
--Check if the next table has any UserId matching the where clause
EXEC('INSERT INTO #Results (Number, ''' + #TableName + ''') SELECT COUNT(UserId) , ''' + #TableName + ''' FROM ' + #TableName + ' WHERE UserId = ''FF13ACCA-022C-4296-AB3D-A35700E35BB3''');
FETCH NEXT FROM db_cursor INTO #TableName;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;
SELECT * FROM #Results
DROP TABLE #Results
I cannot test it but this should be the way

List all columns referenced in all procedures of all databases

Is there a way that I can get all the columns and tables referenced in all the stored procedures in all the databases in an instance? The output should be:
Database Procedure Table Column
-------- --------- ----- ------
This will get the list you're after, however it won't help you if you have such column references embedded in dynamic SQL (and may not find references that rely on deferred name resolution). SQL Server doesn't parse the text of the stored procedure to come up with the DMV output.
Try now with COLLATE clauses to deal with cases where you have databases on the same server with different collations.
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += N'UNION ALL
SELECT
[database] = ''' + REPLACE(name, '''', '''''') + ''',
[procedure] = QUOTENAME(s.name) + ''.'' + QUOTENAME(p.name)
COLLATE Latin1_General_CI_AI,
[table] = QUOTENAME(referenced_schema_name) + ''.''
+ QUOTENAME(referenced_entity_name)
COLLATE Latin1_General_CI_AI,
[column] = QUOTENAME(referenced_minor_name)
COLLATE Latin1_General_CI_AI
FROM ' + QUOTENAME(name) + '.sys.schemas AS s
INNER JOIN ' + QUOTENAME(name) + '.sys.procedures AS p
ON s.[schema_id] = p.[schema_id]
CROSS APPLY ' + QUOTENAME(name)
+ '.sys.dm_sql_referenced_entities'
+ '(QUOTENAME(s.name) + ''.'' + QUOTENAME(p.name), N''OBJECT'') AS d
WHERE d.referenced_minor_id > 0'
FROM sys.databases
WHERE database_id > 4
AND [state] = 0;
SET #sql = STUFF(#sql,1,11,'');
EXEC sp_executesql #sql;
Also the CROSS APPLY syntax won't work if you have databases that are in 80 compatibility mode. Just make sure you don't execute the code in such a database and it should work fine (even if some of the target databases are in 80).
To list all SP Name have contain the specified column name:
SELECT OBJECT_NAME(M.object_id), M.*
FROM sys.sql_modules M
JOIN sys.procedures P
ON M.object_id = P.object_id
WHERE M.definition LIKE '%ColumnName%'
Here is yet another way to do this. This is very DIRTY but I like it. Why? Because I came up with it. Anyway it is using Dynamic SQL inside Dynamic SQL to insert dependency information into temp table that can be queried.
This can be modified into a SP that you can run from time to time to update dependencies information, also temp table can be changes to real table if you want to store it.
IF OBJECT_ID('tempdb.dbo.#SPDependencyDetails') IS NOT NULL
DROP TABLE #SPDependencyDetails
CREATE TABLE #SPDependencyDetails
(
Or_Object_Database NVARCHAR(128)
,Or_Object_Name NVARCHAR(128)
,Ref_Database_Name NVARCHAR(128)
,Ref_Schema_Name NVARCHAR(128)
,Ref_Object_Name NVARCHAR(128)
,Ref_Column_Name NVARCHAR(128)
,Is_Selected BIT
,Is_Updated BIT
,Is_Select_All BIT
,Is_All_Columns_Found BIT
)
DECLARE #database_name VARCHAR(100)
DECLARE database_cursor CURSOR
FOR
SELECT name
FROM sys.databases
WHERE database_id > 4
OPEN database_cursor
FETCH NEXT FROM database_cursor
INTO #database_name
WHILE ##FETCH_STATUS = 0 --Outer Loop begin
BEGIN
DECLARE #WholeLotofSQL NVARCHAR(MAX) = '
DECLARE #object_name VARCHAR(150)
,#sqlstatement NVARCHAR(2500)
DECLARE object_cursor CURSOR --Inner cursor, iterates list of objects that match type
FOR
SELECT name
FROM '+#database_name+'.sys.objects AS o
WHERE o.type = ''P'' --Change Object type to find dependencies of Functions, Views and etc.
ORDER BY 1
OPEN object_cursor
FETCH NEXT FROM object_cursor INTO #object_name
WHILE ##FETCH_STATUS = 0 --Inner Loop Begin
BEGIN
SET #sqlstatement = ''USE '+#database_name+';
INSERT INTO #SPDependencyDetails
SELECT DB_NAME() AS Or_Object_Database
,'''''' + #object_name + '''''' AS Or_Object_Name
,CASE WHEN referenced_database_name IS NULL THEN DB_NAME()
ELSE referenced_database_name
END AS Ref_Database_Name
,referenced_schema_name AS Ref_Schema_Name
,referenced_entity_name AS Ref_Object_Name
,referenced_minor_name AS Ref_Column_Name
,is_selected
,is_updated
,is_select_all
,is_all_columns_found
FROM sys.dm_sql_referenced_entities(''''dbo.'' + #object_name + '''''', ''''OBJECT'''');''
EXEC sys.sp_executesql #sqlstatement
FETCH NEXT FROM object_cursor INTO #object_name
END
CLOSE object_cursor
DEALLOCATE object_cursor'
EXEC sys.sp_executesql #WholeLotofSQL
FETCH NEXT FROM database_cursor INTO #database_name
END
CLOSE database_cursor;
DEALLOCATE database_cursor;
SELECT Or_Object_Database as 'Database'
,Or_Object_Name as 'Procedure'
,Ref_Object_Name as 'Table'
,Ref_Column_Name as 'Column
FROM #SPDependencyDetails

How to drop all stored procedures at once in SQL Server database?

Currently we use separate a drop statements for each stored procedure in the script file:
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]
Is there a way to drop them all at once, or maybe in a loop?
I would prefer to do it this way:
first generate the list of stored procedures to drop by inspecting the system catalog view:
SELECT 'DROP PROCEDURE [' + SCHEMA_NAME(p.schema_id) + '].[' + p.NAME + '];'
FROM sys.procedures p
This generates a list of DROP PROCEDURE statements in your SSMS output window.
copy that list into a new query window, and possibly adapt it / change it and then execute it
No messy and slow cursors, gives you the ability to check and double-check your list of procedure to be dropped before you actually drop it
Something like (Found at Delete All Procedures from a database using a Stored procedure in SQL Server).
Just so by the way, this seems like a VERY dangerous thing to do, just a thought...
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
In the Object Explorer pane, select the Stored Procedures folder.
Press F7 (or from the main menu, choose View > Object Explorer Details).
Select all procedures except the System Table.
Press Delete button and select OK.
You can delete Tables or Views in the same manner.
create below stored procedure in your db(from which db u want to delete sp's)
then right click on that procedure - click on Execute Stored Procedure..
then click ok.
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
I think this is the simplest way:
DECLARE #sql VARCHAR(MAX)='';
SELECT #sql=#sql+'drop procedure ['+name +'];' FROM sys.objects
WHERE type = 'p' AND is_ms_shipped = 0
exec(#sql);
To get drop statements for all stored procedures in a database
SELECT 'DROP PROCEDURE' + ' '
+ F.NAME + ';'
FROM SYS.objects AS F where type='P'
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);
Try this, it work for me
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;
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
Try this:
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;
ANSI compliant, without cursor
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)
Without cursor, non-ansi compliant:
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)
By mixing the cursor and system procedure, we would have a optimized solution, as follow:
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
ANSI compliant, without cursor
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
Try this:
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