2008-11-25 12 views

Répondre

24

Vous déplacer des objets individuels d'un schéma à un autre via:

ALTER SCHEMA NewSchema TRANSFER OldSchema.Object; 
+7

Vous devez d'abord utiliser 'CREATE SCHEMA NewSchema'. – thomaspaulb

+1

@littlegreen: Vous pouvez supposer que le schéma a déjà été créé car l'utilisateur a demandé comment renommer, pas créer. – Phil

+4

@Phil - pas vraiment. Si quelqu'un d'autre a créé 'OldSchema' et que la pensée intuitive est de * renommer * plutôt que d'en créer un nouveau et de lui transférer des objets, il n'est pas certain que l'utilisateur sache créer le nouveau schéma en premier. –

30

Si vous avez un grand nombre d'objets dans un schéma, vous pouvez utiliser quelque chose comme ceci pour générer tous les changements automatiquement (il ne fait tables et vues, donc avant de l'exécuter, vous pourriez avoir besoin de l'étendre à SPs, UDFs, etc.)

USE SandBox 

DECLARE @OldSchema AS varchar(255) 
DECLARE @NewSchema AS varchar(255) 

SET @OldSchema = 'dbo' 
SET @NewSchema = 'StackOverflow' 

DECLARE @sql AS varchar(MAX) 

SET @sql = 'CREATE SCHEMA [' + @NewSchema + ']' + CHAR(13) + CHAR(10) 

SELECT @sql = @sql + 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']' 
    + CHAR(13) + CHAR(10) 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA = @OldSchema 

SET @sql = @sql + 'DROP SCHEMA [' + @OldSchema + ']' 

PRINT @sql -- NOTE PRINT HAS AN 8000 byte limit - 8000 varchar/4000 nvarchar - see comments 
IF (0=1) EXEC (@sql) 
+0

+1. Merci Cade, tu m'as sauvé un tas de travail! –

+0

Cela ne fonctionne pas très bien si les vues contiennent des références à l'oldschema en eux, malheureusement :( –

+0

@mgroves Oui, mais les objets dans un schéma ne nécessitent pas d'autres objets dans le même schéma à être préfixé, donc c'est probablement un design En premier lieu, vous pouvez essayer de saisir ce problème en utilisant le code de vue ou de proc (stocké dans les métadonnées) pour rechercher d'éventuels abus de préfixes Vous pouvez intercepter les problèmes potentiels d'analyse après un mouvement de masse en essayant de rafraîchir tous les modules SQL (non déterministes) –

2

pour les procédures

USE DatabaseName 

DECLARE @OldSchema AS varchar(255) 
DECLARE @NewSchema AS varchar(255) 

SET @OldSchema = 'ComputerLearn' 
SET @NewSchema = 'Basic' 

DECLARE @sql AS varchar(MAX) 

SET @sql = 'CREATE SCHEMA [' + @NewSchema + ']' + CHAR(13) + CHAR(10) 

SELECT @sql = @sql + 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + sys.schemas.name + '].[' + sys.procedures.name + ']' 
    + CHAR(13) + CHAR(10) 
FROM sys.procedures,sys.schemas 
WHERE sys.procedures.schema_id=sys.schemas.schema_id and sys.schemas.name = @OldSchema 

SET @sql = @sql + 'DROP SCHEMA [' + @OldSchema + ']' 

PRINT @sql 
IF (0=1) EXEC (@sql) 
+0

SI (0 = 1) EXEC (@sql) ce sera toujours faux, donc je pense qu'il faut enlever la partie IF de la dernière ligne, sinon ça fonctionne comme du charme !!! un vote de moi. – sib10

14

J'ai combiné les deux codes ci-dessus et utilisé les curseurs pour ne pas être limité par la taille des variables de chaîne, en exécutant les commandes individuellement. Je suppose que vous avez déjà créé le nouveau schéma et abandonnerez l'ancien après avoir certifié que tout est ok. Il est plus sûr ... :)

DECLARE @OldSchema AS varchar(255) 
DECLARE @NewSchema AS varchar(255) 

SET @OldSchema = 'dbo' 
SET @NewSchema = 'StackOverflow' 

DECLARE @sql AS varchar(MAX) 

DECLARE @Schema AS varchar(MAX) 
DECLARE @Obj AS varchar(MAX) 

-- First transfer Tables and Views 

DECLARE CU_OBJS CURSOR FOR 
    SELECT TABLE_SCHEMA, TABLE_NAME 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_SCHEMA = @OldSchema 

OPEN CU_OBJS 

FETCH NEXT FROM CU_OBJS 
INTO @Schema, @Obj 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @sql = 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + @OldSchema + '].[' + @Obj + ']' 
    PRINT @sql 
-- EXEC (@sql) 

    FETCH NEXT FROM CU_OBJS 
    INTO @Schema, @Obj 
END 

CLOSE CU_OBJS 
DEALLOCATE CU_OBJS 


-- Now transfer Stored Procedures 

DECLARE CU_OBJS CURSOR FOR 
    SELECT sys.schemas.name, sys.procedures.name 
    FROM sys.procedures,sys.schemas 
    WHERE sys.procedures.schema_id=sys.schemas.schema_id and sys.schemas.name = @OldSchema 

OPEN CU_OBJS 

FETCH NEXT FROM CU_OBJS 
INTO @Schema, @Obj 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @sql = 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + @Schema + '].[' + @Obj + ']' 
    PRINT @sql 
-- EXEC (@sql) 

    FETCH NEXT FROM CU_OBJS 
    INTO @Schema, @Obj 
END 

CLOSE CU_OBJS 
DEALLOCATE CU_OBJS 
+3

Je pense que vous avez l'ordre des arguments inversés sur la première ligne 'ALTER'. Le '@ NewSchema' devrait être listé en premier, après' ALTER SCHEMA', mais vous montrerez '@ OldSchema' en premier. Sinon, ça marche plutôt bien. Il ne renomme pas les schémas en profondeur (références dans sp ou vues), mais aucune de ces solutions ne le fait non plus. –

+0

@AlanMcBee Merci d'avoir signalé le swap de schéma! M'avait troublé pendant un moment :) – FreakinOutMan

+0

Cela devrait être la réponse acceptée – Kunal

3

La procédure stockée pour renommer le schéma qui a plusieurs tables dans SQL Server 2008

IF OBJECT_ID ('dbo.RenameSchema', 'P') IS NOT NULL 
    DROP PROCEDURE dbo.RenameSchema; 
    GO       

CREATE PROCEDURE dbo.RenameSchema    

@OLDNAME varchar(500), 
@NEWNAME varchar(500) 

AS    
    /*check for oldschema exist or not */ 
    IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = @OLDNAME) 

     BEGIN 

      RETURN 

     END 

     /* Create the schema with new name */ 
     IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = @NEWNAME) 

     BEGIN 

      EXECUTE('CREATE SCHEMA ' + @NEWNAME); 

     END     

    /* get the object under the old schema and transfer those objects to new schema */ 
    DECLARE Schema_Cursor CURSOR FOR 

    SELECT ' ALTER SCHEMA ' + @NEWNAME + ' TRANSFER '+ SCHEMA_NAME(SCHEMA_ID)+'.'+ name 
    as ALTSQL from sys.objects WHERE type IN ('U','V','P','Fn') AND 
    SCHEMA_NAME(SCHEMA_ID) = @OLDNAME; 

    OPEN Schema_Cursor;   

    DECLARE @SQL varchar(500)   

    FETCH NEXT FROM Schema_Cursor INTO @SQL; 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
    exec (@SQL) 
    FETCH NEXT FROM Schema_Cursor INTO @SQL; 
    END; 

    CLOSE Schema_Cursor; 

    DEALLOCATE Schema_Cursor; 

    /* drop the old schema which should be the user schema */ 
    IF @OLDNAME <> 'dbo' and @OLDNAME <> 'guest' 
    BEGIN 
    EXECUTE ('DROP SCHEMA ' + @OLDNAME) 
    END 
    GO 

Exécutez la procédure pour renommer le schéma: exemples:

EXECUTE RenameSchema 'oldname','newname' 
    EXECUTE RenameSchema 'dbo','guest' 
+0

A travaillé pour mi dans SQL Server 2012. Merci! – Faliorn

0

La solution la plus simple qui a fonctionné pour moi est:
J'ai juste un schéma dbo avec deux tables PopulationByCountrySTG et CountryRegionSTG

(1) I a créé un nouveau schéma en exécutant,

create schema stg 

(2) I exécuté les commandes suivantes,

ALTER SCHEMA stg TRANSFER dbo.PopulationByCountrySTG; 
ALTER SCHEMA stg TRANSFER dbo.CountryRegionSTG; 

tout fait. Faites-moi savoir si cela fonctionne pour vous .. Merci les gars.

2

Ceci est une version courte mais fonctionne bien.

declare @sql varchar(8000), @table varchar(1000), @oldschema varchar(1000), @newschema varchar(1000) 

    set @oldschema = 'old' 
    set @newschema = 'dbo' 

while exists(select * from sys.tables where schema_name(schema_id) = @oldschema) 

    begin 
     select @table = name from sys.tables 
     where object_id in(select min(object_id) from sys.tables where schema_name(schema_id) = @oldschema) 

    set @sql = 'alter schema [' + @newschema + '] transfer [' + @oldschema + '].[' + @table + ']' 

    exec(@sql) 
end 
+1

Merci pour ça! Dans mon cas, je passais à un nouveau schéma, et je devais d'abord penser 'CREATE SCHEMA [newSchema]'! –

Questions connexes