Déplacement de tables vers une autre base de données SQL2008 (y compris les index, les déclencheurs, etc.)

16

J'ai besoin de déplacer un tas (100+) de grandes tables (des millions de lignes) d'une base de données SQL2008 à une autre.

À l'origine, je viens d'utiliser l'assistant d'importation / exportation, mais toutes les tables de destination manquaient de clés primaires et étrangères, d'index, de contraintes, de déclencheurs, etc. (les colonnes d'identité ont également été converties en INT simples, mais je pense que j'ai raté une case à cocher dans sorcier.)

Quelle est la bonne façon de procéder?

S'il ne s'agissait que de quelques tables, je retournerais à la source, je rédigerais la définition de la table (avec tous les index, etc.), puis exécuterais les parties de création d'index du script sur la destination. Mais avec autant de tableaux, cela semble peu pratique.

S'il n'y avait pas autant de données, je pourrais utiliser l'assistant "Créer des scripts ..." pour créer un script pour la source, y compris les données, mais un script de 72 m de ligne ne semble tout simplement pas être une bonne idée!

BradC
la source
Et ce ne sont pas toutes les tables de la base de données?
thursdaysgeek
@thursdaysgeek: Ses presque toutes les tables, mais la base de données de destination contient déjà plus de 100 tables. La restauration à partir d'une sauvegarde avec un nom différent n'est donc pas une option. Considérez ceci comme fondamentalement «fusionnez ces deux grandes bases de données ensemble».
BradC

Réponses:

14

Scénariser les tables, puis utiliser SSIS pour transférer les données serait le moyen le plus fiable et le plus efficace de déplacer les données vers la nouvelle base de données.

mrdenny
la source
9

Nous l'avons fait en utilisant beaucoup de scripts manuels en conjonction avec l'assistant d'importation, mais ce matin, j'ai trouvé une meilleure réponse, gracieuseté de l'article de blog de Tibor Karaszi .

Une partie de notre frustration était que l ' «Assistant d'importation / exportation DTS» de SQL 2000 rend cela très facile en sélectionnant «Copier les objets et les données»:

Assistant d'importation DTS

Cette troisième option est celle qui contient la possibilité d'inclure des index / déclencheurs, etc.:

Options avancées

Cette option a été SUPPRIMÉE de l' Assistant d'importation SQL 2005/2008 . Pourquoi? Aucune idée:

Assistant d'importation 2008

En 2005/2008, vous devez apparemment créer manuellement un package SSIS dans BIDS et utiliser la tâche de transfert d'objets SQL Server , qui contient toutes les mêmes options que celles de l'assistant 2000:

Tâche SSIS de transfert d'objets SQL Server

BradC
la source
Je voulais juste signaler que j'ai utilisé cette méthode SSIS pour une autre tâche similaire, et cela a très bien fonctionné!
BradC
8

J'envisagerais de créer un script pour la table ou d'utiliser un outil de comparaison (par exemple, Red Gate) pour générer les tables dans la base de données cible. Sans index ni contraintes pour le moment.

J'envisagerais alors de restaurer la base de données avec un nom différent sur le même serveur et de faire

 INSERT newdb.dbo.newtable SELECT * FROM olddb.dbo.oldtable

.. pour chaque table, avec SET IDENTITY INSERT ON si nécessaire

Ensuite, j'ajoutais des index et des contraintes après le chargement des données.

Cela dépend de votre niveau de confort avec SSIS (réponse de mrdenny) ou si vous préférez du SQL brut.

gbn
la source
6

J'ajouterais à la réponse de M. Denny: Scriptez le schéma des tables puis utilisez BCP pour déplacer les données. Si vous n'êtes pas familier avec SSIS, l'utilisation de BCP et des lots devrait être facile à faire. Pour des millions de lignes, rien ne vaut BCP (encart en vrac) :).

Marian
la source
4

Je suis celui qui est complètement mal à l'aise avec SSIS.

Lorsque les tables source n'ont pas de colonnes d'identité

  1. créer une base de données vide sur le serveur cible
  2. créer un serveur lié au serveur source sur le serveur cible
  3. exécutez le script ci-dessous sur la base de données source pour générer les instructions select * into ...
  4. exécuter le script généré à partir de la base de données cible
  5. clés primaires de script, index, déclencheurs, fonctions et procédures de la base de données source
  6. créer ces objets par le script généré

Maintenant, le T-SQL pour générer les instructions Select * into ...

SET NOCOUNT ON

declare @name sysname
declare @sql varchar(255)

declare db_cursor cursor for
select name from sys.tables order by 1
open db_cursor

fetch next from db_cursor into @name
while @@FETCH_STATUS = 0
begin
    Set @sql = 'select * into [' + @name + '] from [linked_server].[source_db].[dbo].[' + @name + '];'
    print @sql

    fetch next from db_cursor into @name
end

close db_cursor
deallocate db_cursor

Cela génère une ligne pour chaque table à copier comme

select * into [Table1] from [linked_server].[source_db].[dbo].[Table1];

Dans le cas où les tables contiennent des colonnes d'identité, je script les tables, y compris la propriété d'identité et les clés primaires.

Je n'utilise pas d'insertion dans ... sélectionnez ... en utilisant un serveur lié dans ce cas, car ce n'est pas une technique en vrac. Je travaille sur certains scripts PowerShell similaires à [cette question SO 1 , mais je travaille toujours sur la gestion des erreurs. Les très grandes tables peuvent provoquer des erreurs de mémoire insuffisante, car une table entière est chargée en mémoire, avant d'être envoyée via SQLBulkCopy à la base de données.

La récréation des index, etc. est similaire au cas ci-dessus. Cette fois, je peux sauter la recréation des clés primaires.

bernd_k
la source
Dans le cas où les tables contiennent des colonnes d'identité, vous pouvez faire comme dans cette question . Cela vous fera économiser du travail manuel. Je préfère toujours les lots d'insertion en vrac / SSIS, le serveur lié peut ne pas être une bonne solution sur un large réseau.
Marian
1
@Marian Veuillez consulter dba.stackexchange.com/questions/297/… si vous souhaitez promouvoir SSIS. Je n'ai pas essayé SSIS, mais l'assistant d'importation et d'exportation a également échoué (en plus du serveur lié).
bernd_k
J'aurais aidé avec plaisir, mais je n'ai pas de boîte Oracle à ma disposition. Quoi qu'il en soit, d'après ce que j'ai réussi à lire, il n'y a pas de fournisseurs qui prendront en charge Oracle CLOB ..
Marian
Je suis avec vous à ce sujet - je migre parfois des données, mais je n'utilise jamais SSIS.
AK
2

Vous pouvez utiliser des outils de comparaison qui comparent les schémas de base de données et les données et synchroniser d'abord un schéma de base de données vierge avec la base de données d'origine, pour créer toutes les tables.

Ensuite, synchronisez les données de la base de données d'origine avec la nouvelle (toutes les tables sont là, mais elles sont toutes vides) pour insérer les enregistrements dans les tables

J'utilise ApexSQL Diff et ApexSQL Data Diff pour cela, mais il existe d'autres outils similaires.

La bonne chose à propos de ce processus est que vous n'avez pas vraiment à synchroniser les bases de données à l'aide de l'outil, car cela peut être assez pénible pour des millions de lignes.

Vous pouvez simplement créer un script SQL INSERT INTO (ne soyez pas surpris s'il s'agit de plusieurs concerts) et l'exécuter.

Comme les scripts de grande taille ne peuvent même pas être ouverts dans SQL Server Management Studio, j'utilise sqlcmd ou osql

Carol Baker West
la source
1

Comme l'a mentionné @mrdenny -

  1. scriptez d'abord les tables avec tous les index, FK, etc. et créez des tables vides dans la base de données de destination.

Au lieu d'utiliser SSIS, utilisez BCP pour insérer des données

  1. bcp sortir les données en utilisant le script ci-dessous. définissez SSMS en mode texte et copiez la sortie générée par le script ci-dessous dans un fichier bat.

    -- save below output in a bat file by executing below in SSMS in TEXT mode
    
    -- clean up: create a bat file with this command --> del D:\BCP\*.dat 
    
    select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" ' /* path to BCP.exe */
        +  QUOTENAME(DB_NAME())+ '.' /* Current Database */
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
        +  QUOTENAME(name)  
        +  ' out D:\BCP\'  /* Path where BCP out files will be stored */
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
        +  REPLACE(name,' ','') 
        + '.dat -T -E -SServerName\Instance -n' /* ServerName, -E will take care of Identity, -n is for Native Format */
    from sys.tables
    where is_ms_shipped = 0 and name <> 'sysdiagrams'                       /* sysdiagrams is classified my MS as UserTable and we dont want it */
    /*and schema_name(schema_id) <> 'unwantedschema'    */                             /* Optional to exclude any schema  */
    order by schema_name(schema_id)
  2. Exécutez le fichier bat qui générera les fichiers .dat dans le dossier que vous avez spécifié.

  3. Exécutez le script ci-dessous sur le

    --- Execute this on the destination server.database from SSMS.
    
    --- Make sure the change the @Destdbname and the bcp out path as per your environment.
    
    declare @Destdbname sysname
    set @Destdbname = 'destinationDB' /* Destination Database Name where you want to Bulk Insert in */
    select 'BULK INSERT ' 
    /*Remember Tables must be present on destination database */ 
    + QUOTENAME(@Destdbname) + '.' 
    + QUOTENAME(SCHEMA_NAME(SCHEMA_ID)) 
    + '.' + QUOTENAME(name) 
    + ' from ''D:\BCP\' /* Change here for bcp out path */ 
    + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') 
    + '.dat'' with ( KEEPIDENTITY, DATAFILETYPE = ''native'', TABLOCK )' 
    + char(10) 
    + 'print ''Bulk insert for ' + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') + ' is done... ''' 
    + char(10) + 'go'
       from sys.tables
       where is_ms_shipped = 0
    and name <> 'sysdiagrams' /* sysdiagrams is classified my MS as UserTable and we dont want it */
    and schema_name(schema_id) <> 'unwantedschema' /* Optional to exclude any schema */
        order by schema_name(schema_id) 
  4. Exécutez la sortie à l'aide de SSMS pour réinsérer les données dans les tables.

C'est une méthode bcp très rapide car elle utilise le mode natif.

Kin Shah
la source