web-dev-qa-db-fra.com

Comment changer le schéma de toutes les tables, vues et procédures stockées dans MSSQL

Récemment, nous avions des problèmes sur notre serveur de base de données et après de longs efforts, il a été décidé de changer le serveur de base de données. Nous avons donc réussi à restaurer la base de données sur un autre serveur, à modifier la chaîne de connexion, etc. Tout se déroulait comme prévu jusqu'à ce que nous essayions d'accéder au site Web à partir d'un navigateur Web.

Nous avons commencé à obtenir des erreurs sur les objets de base de données introuvables. Plus tard, nous avons découvert qu'il s'est produit en raison du nom de schéma modifié. Puisqu'il y a des centaines d'objets de base de données (tables, vues et procédures stockées) dans une base de données Kentico, il n'est pas possible de les modifier tous manuellement, un par un. Existe-t-il un moyen pratique de procéder?

24
anar khalilov

Oui, c'est possible.

Pour modifier le schéma d'un objet de base de données, vous devez exécuter le script SQL suivant:

ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.ObjectName

Où ObjectName peut être le nom d'une table, d'une vue ou d'une procédure stockée. Le problème semble être d'obtenir la liste de tous les objets de base de données avec un nom de shcema donné. Heureusement, il existe une table système nommée sys.Objects qui stocke tous les objets de base de données. La requête suivante générera tous les scripts SQL nécessaires pour effectuer cette tâche:

SELECT 'ALTER SCHEMA NewSchemaName TRANSFER [' + SysSchemas.Name + '].[' + DbObjects.Name + '];'
FROM sys.Objects DbObjects
INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id = SysSchemas.schema_id
WHERE SysSchemas.Name = 'OldSchemaName'
AND (DbObjects.Type IN ('U', 'P', 'V'))

Où le type "U" désigne les tables utilisateur, "V" les vues et "P" les procédures stockées.

L'exécution du script ci-dessus générera les commandes SQL nécessaires pour transférer des objets d'un schéma à un autre. Quelque chose comme ça:

ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.CONTENT_KBArticle;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Proc_Analytics_Statistics_Delete;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Proc_CMS_QueryProvider_Select;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.COM_ShoppingCartSKU;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.CMS_WebPart;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Polls_PollAnswer;

Vous pouvez maintenant exécuter toutes ces requêtes générées pour terminer l'opération de transfert.

84
anar khalilov

Voici le SQL que j'ai exécuté, pour déplacer toutes les tables de ma base de données (réparties sur plusieurs schémas) dans le schéma "dbo":

DECLARE 
    @currentSchemaName nvarchar(200),
    @tableName nvarchar(200)

DECLARE tableCursor CURSOR FAST_FORWARD FOR 
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY 1, 2

DECLARE @SQL nvarchar(400)

OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO @currentSchemaName, @tableName

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQL = 'ALTER SCHEMA dbo TRANSFER ' + @currentSchemaName + '.' + @tableName
    PRINT @SQL

    EXEC (@SQL)

    FETCH NEXT FROM tableCursor INTO @currentSchemaName, @tableName
END

CLOSE tableCursor 
DEALLOCATE tableCursor 

Phew!

3
Mike Gledhill

Merci pour l'astuce .. Voici ma mise à jour de même, où j'ai ajouté un crlf à la sortie ainsi que des crochets autour de SchemaName et ObjectName, car certains des objets avaient un '-' dans le nom et les crochets ont résolu cette dénomination Erreur.

SELECT 'ALTER SCHEMA NewSchemaName TRANSFER [' + SysSchemas.Name + '].[' +      DbObjects.Name + '];'
+ CHAR(13)+ CHAR(10)+ 'GO '+ CHAR(13)+ CHAR(10)
FROM sys.Objects DbObjects
INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id =     SysSchemas.schema_id
WHERE SysSchemas.Name = 'OldSchemaName'
AND (DbObjects.Type IN ('U', 'P', 'V'))
2
Hank Freeman

Vous pouvez utiliser le script suivant en copiant/collant simplement pour tous les objets

[~ # ~] note [~ # ~] : vous devez modifier noms de schéma dans le script!

DECLARE @OldSchema VARCHAR(200)
DECLARE @NewSchema VARCHAR(200)
DECLARE @SQL nvarchar(4000)
SET @OldSchema = 'dbo'
SET @NewSchema = 'Inf'

DECLARE tableCursor CURSOR FAST_FORWARD FOR 
    SELECT 'ALTER SCHEMA  ['+ @NewSchema +'] TRANSFER [' + SysSchemas.Name + '].[' + DbObjects.Name + '];' AS Cmd
    FROM sys.Objects DbObjects
    INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id = SysSchemas.schema_id
    WHERE SysSchemas.Name = @OldSchema
    AND (DbObjects.Type IN ('U', 'P', 'V'))
OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO  @SQL
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @SQL
    EXEC (@SQL)
    FETCH NEXT FROM tableCursor INTO  @SQL
END
CLOSE tableCursor 
DEALLOCATE tableCursor 
PRINT '*** Finished ***'
1
Haseeb Ahmed