如何使用游标在不同的数据库中创建过程

How to Create Procedures In Different Databases Using Cursor

所以我试图在不同的数据库中制作程序。我不应该知道数据库的名称。我尝试制作嵌套游标,第一个以动态方式获取数据库名称,另一个以 create/alter 过程;我使用 EXISTS 来创建过程,使用 NOT EXISTS 来改变它们。但不知何故数据库坚持 'master' 并且它永远不会循环遍历其他数据库。我知道我的内部嵌套光标有问题,但我不知道这是什么。 这是我的编码:

DECLARE GetDatabases CURSOR
FOR
    SELECT name
    FROM sys.databases
OPEN GetDatabases
DECLARE @DBName NVARCHAR(100)
DECLARE @cmd NVARCHAR(Max)

FETCH NEXT
FROM GetDatabases
INTO @DBName

WHILE @@FETCH_STATUS = 0
BEGIN
    set @cmd='use ' + @DBName
    print @cmd
    exec sp_executesql @cmd
     FETCH NEXT
     FROM GetDatabases
     INTO @DBName
        DECLARE AutoProc CURSOR
        FOR
            SELECT TABLE_SCHEMA,TABLE_NAME
            FROM INFORMATION_SCHEMA.TABLES
            WHERE TABLE_TYPE='BASE TABLE'
        OPEN AutoProc
        DECLARE @TableName NVARCHAR(100)
        DECLARE @TableSchema NVARCHAR(100)

        FETCH NEXT
        FROM AutoProc
        INTO @TableSchema,@TableName

        WHILE @@FETCH_STATUS = 0
        BEGIN
        IF EXISTS(SELECT * FROM sys.objects WHERE type = 'P' AND OBJECT_ID = OBJECT_ID('@TableName'))
            exec('ALTER PROCEDURE USP_SELECT_'+@TableName+' AS
            BEGIN
            SELECT *
            FROM '+@TableSchema+'.'+@TableName+'
            END ;')
        IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND OBJECT_ID = OBJECT_ID('@TableName'))
            exec('CREATE PROCEDURE USP_SELECT_'+@TableName+' AS
            BEGIN
            SELECT *
            FROM '+@TableSchema+'.'+@TableName+'
            END ;')
             FETCH NEXT
             FROM AutoProc
             INTO @TableSchema,@TableName
        END 
        CLOSE AutoProc
        DEALLOCATE AutoProc
END 
CLOSE GetDatabases
DEALLOCATE GetDatabases

P.S:我不应该知道数据库的名称,因为我正在尝试编写一个 "General" 程序以便它可以应用于所有 sql-服务器用户的数据库,不仅仅是我的。

P.S2:我使用了 Nesting Cursors,但由于其糟糕的性能,我也希望使用其他方式!

干杯!

尝试使用 while 语句并遍历临时变量 table,而不是使用游标。

DECLARE @Databases TABLE
 (
   ID int IDENTITY(1,1),
   DatabaseName varchar(100)
 )


INSERT INTO @Databases
SELECT name FROM sys.databases

DECLARE @Idx int = (select count(*) from @Databases)

 WHILE(@Idx > 0)
   BEGIN 

    DECLARE @CurrentDatabase varchar(100) = (select DatabaseName from @Databases where @Idx = ID )

    DECLARE @SchemaData TABLE
    (
     ID int IDENTITY(1,1),
     Table_Schema varchar(20),
     Table_Name varchar(255)
    )

    DECLARE @Sql varchar(max) = 'SELECT [TABLE_SCHEMA],[TABLE_NAME] FROM [' + @CurrentDatabase + '].[INFORMATION_SCHEMA].[TABLES]'     

    INSERT INTO @SchemaData
      EXEC (@Sql)

    DECLARE @SchemaIdx int = (select count(*) from @SchemaData)

    WHILE(@SchemaIdx > 0)
      BEGIN

      DECLARE @CurrentSchema varchar(20), @CurrentTable varchar(255)

      SELECT @CurrentSchema = Table_Schema, @CurrentTable = Table_Name from      @SchemaData where ID = @SchemaIdx

      DECLARE @Sql2 varchar(max) = 
          'IF EXISTS(SELECT * FROM sys.objects WHERE type = ''P'' AND OBJECT_ID = OBJECT_ID(' + @CurrentTable + '))
          exec(''ALTER PROCEDURE USP_SELECT_'+ @CurrentTable + ' AS
          BEGIN
          SELECT *
          FROM '+ @CurrentSchema + '.'+ @CurrentTable + '
          END ;'')'

      PRINT @Sql2

      SET @SchemaIdx = @SchemaIdx - 1;
     END



  SET @Idx = @Idx - 1;
 END