Search code examples
sql-serverstored-procedurescopy

Copying stored procedures and changing database reference


I have a stored procedure that copies all the stored procedures in one database to another, changing the database reference. However, it currently has to be run on the destination db, whereas I would prefer to run it on the source db. I'm unsure how to point the relevant statement to the correct db.

-- Delete all procedures in TO database - must run on TO db
DECLARE @procName varchar(500)
DECLARE cur1 cursor FOR 
    SELECT [name] FROM [DestDB].sys.objects WHERE type = 'p'
OPEN cur1
FETCH NEXT FROM cur1 INTO @procName
WHILE @@fetch_status = 0
BEGIN
    EXEC('drop procedure [' + @procName + ']')  --Problem statement
    FETCH NEXT FROM cur1 INTO @procName
END
CLOSE cur1
DEALLOCATE cur1

-- Copy all procedures from FROM database
DECLARE @sql NVARCHAR(MAX); 
DECLARE @Name NVARCHAR(32) = 'DestDB'; --TO database
DECLARE cur2 CURSOR FOR 
   SELECT Definition
   FROM [SourceDB].[sys].[procedures] p
   INNER JOIN [SourceDB].sys.sql_modules m ON p.object_id = m.object_id
OPEN cur2
FETCH NEXT FROM cur2 INTO @sql
WHILE @@FETCH_STATUS = 0 
BEGIN
   SET @sql = REPLACE(@sql,'''','''''')
   SET @sql = 'USE [' + @Name + ']; EXEC(''' + @sql + ''')'
   EXEC(@sql)
   FETCH NEXT FROM cur2 INTO @sql
END             
CLOSE cur2
DEALLOCATE cur2

The problem is the 'drop procedure ' call. You can't specify the database in the call, so it operates on the active one. I need to be able to specify the database that the 'drop procedure' runs on, so I can run the procedure from the source db.


Solution

  • Why do you not use a 'USE' statement before the drop, as you are doing later inside the CURSOR?

    EXEC('USE [' + @Name + ']; drop procedure [' + @procName + ']') 
    

    Simply DECLARE the @Name variable earlier. It should work assuming all the procs are in the same database. "CREATE OR ALTER" should also complete the task, as mentioned, if you're using SQL Server 2016 and above.