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.
3条答案
按热度按时间xqnpmsa81#
Why do you not use a 'USE' statement before the drop, as you are doing later inside the CURSOR?
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.
ux6nzvsh2#
Rather than
EXEC (<SQL>)
syntax, which is advised against, usesys.sp_executesql
. YOu could then either you could prefix with the procedure with relevant database, such asTestDB.sys.sp_executesql
, or you could assign the procedure name to a variable,SET @ProcName = N'TestDB.sys.sp_executesql'
and then useEXEC @ProcName
.When you execute a procedure, it runs in the context of that database, so
DROP PROC YourProc
would drop a procedure in the procedure in the other database.Note that in the below, you get different database IDs:
So,
DROP
ing a procedure would loom like this:tcbh2hod3#
For reference, this is what I wound up with: