3

我有 100 个数据库,我需要对一个过程进行更改,它们都有相同的过程。如何添加允许我进行此更改的光标?

DECLARE @databasename varchar(100)
DECLARE @Command nvarchar(200)

DECLARE database_cursor CURSOR FOR
SELECT name
FROM MASTER.sys.sysdatabases

OPEN database_cursor

FETCH NEXT FROM database_cursor INTO @databasename

WHILE @@FETCH_STATUS = 0
BEGIN
     SELECT @Command = 'ALTER PROCEDURE ''' + @databasename + '''.[dbo].[DeleteAccountUpgrade]
               @Id INT
            AS
                DELETE FROM AccountUpgrades WHERE Id = @Id'
     EXEC sp_executesql @Command

     FETCH NEXT FROM database_cursor INTO @databasename
END

CLOSE database_cursor
DEALLOCATE database_cursor 

它说我需要声明@Id,但我不明白为什么,我只想在每个数据库上运行该更改,我没有发送任何数据来执行该过程,我只想修改所有数据库上的现有过程。

4

2 回答 2

1

您需要单独使用EXEC,而不是与sp_executesql.

EXEC sp_executesql @Command

应改为:

EXEC(@Command)

sp_executesql过程使用变量进行参数化。这就是错误的来源。另请参阅https://stackoverflow.com/a/16308447/1822514

于 2013-05-06T15:58:46.593 回答
1

使用嵌套 sp_executesql 调用。这允许您对其他数据库执行 DDL。

DECLARE @databasename varchar(100)
DECLARE @Command nvarchar(200)

DECLARE database_cursor CURSOR FOR
SELECT name
FROM MASTER.sys.sysdatabases

OPEN database_cursor

FETCH NEXT FROM database_cursor INTO @databasename

WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT @Command = N'USE ' + QUOTENAME(@databasename) +
                     ' EXEC sp_executesql N''ALTER PROCEDURE [dbo].[DeleteAccountUpgrade] ' +
                     '@Id INT ' +
                     'AS ' +
                     'DELETE FROM AccountUpgrades WHERE Id = @Id'''
  --PRINT @Command
  EXEC sp_executesql @Command

  FETCH NEXT FROM database_cursor INTO @databasename
END

CLOSE database_cursor
DEALLOCATE database_cursor 
于 2013-05-06T20:53:44.877 回答