2009-07-29 3 views
4

Je dois copier un tas de données d'une table de base de données dans une autre. Je ne peux pas utiliser SELECT ... INTO parce que l'une des colonnes est une colonne d'identité. En outre, j'ai quelques modifications à apporter au schéma. J'ai été en mesure d'utiliser l'assistant d'exportation de données pour créer un package SSIS, que j'ai ensuite modifié dans Visual Studio 2005 pour apporter les modifications souhaitées et autres joyeusetés. C'est certainement plus rapide qu'un INSERT INTO, mais il me semble stupide de télécharger les données sur un autre ordinateur juste pour le télécharger de nouveau. (En supposant que j'ai raison de dire que c'est ce que fait le paquetage SSIS). Existe-t-il un équivalent à BULK INSERT qui s'exécute directement sur le serveur, permet de conserver les valeurs d'identité et extrait les données d'une table? (pour autant que je sache, BULK INSERT ne peut extraire que des données d'un fichier)BULK INSERT d'une table à une autre toutes sur le serveur

Editer: Je connais IDENTITY_INSERT, mais comme il y a pas mal de données impliquées, INSERT INTO ... SELECT est un peu de lent. SSIS/BULK INSERT vide les données dans la table sans tenir compte des index et de la consignation, et ainsi de suite, donc c'est plus rapide. (Bien sûr, créer l'index cluster sur la table une fois qu'il est peuplé n'est pas rapide, mais il est encore plus rapide que le INSERT INTO ... SELECT que j'ai essayé dans ma première tentative)

Éditer 2: Les changements de schéma comprennent (mais ne sont pas limités à) ce qui suit: 1. Diviser une table en deux nouvelles tables. Dans le futur, chacun aura sa propre colonne IDENTITY, mais pour la migration, je pense qu'il sera plus simple d'utiliser l'identité de la table d'origine comme identité pour les deux nouvelles tables. Une fois la migration terminée, l'une des tables aura une relation un-à-plusieurs avec l'autre. 2. Déplacement de colonnes d'une table à une autre. 3. Suppression de certaines tables de références croisées qui ne font que des références croisées 1-à-1. Au lieu de cela, la référence sera une clé étrangère dans l'une des deux tables. 4. Certaines nouvelles colonnes seront créées avec des valeurs par défaut. 5. Certaines tables ne changent pas du tout, mais je dois les recopier en raison de la requête "Tout mettre dans une nouvelle base de données".

Répondre

0

Depuis tant de gens se sont penchés sur cette question, je pensais que je devrais suivi. J'ai fini par coller avec le paquet SSIS. Je l'ai exécuté sur le serveur de base de données lui-même. Il est encore passé par le rigmarole de tirer des données du processus sql vers le processus SSIS, puis de le renvoyer. Mais globalement, il a été exécuté plus rapidement que les autres options sur lesquelles j'ai enquêté.

De plus, j'ai rencontré un bogue: lorsque je tirais des données d'une vue, le paquet se bloquait.J'ai fini par couper et coller la requête de la vue directement dans le champ "sql query" de l'objet "source" dans SSIS. Cela semblait seulement se produire lorsque le paquet fonctionnait sur la même machine que le serveur. Lors de l'exécution à partir d'une machine différente, je n'ai pas rencontré cette erreur.

Si je devais tout recommencer, je générerais probablement de nouvelles valeurs d'identité. Je voudrais migrer les anciens vers une colonne dans la nouvelle table, utiliser ces valeurs pour associer les clés étrangères des autres tables, puis je supprimerais la colonne une fois la migration terminée et stable. D'un autre côté, dans l'ensemble, la méthode du paquetage SSIS fonctionnait bien, donc si vous devez faire une migration complexe (découper des tables, etc.) ou si vous avez besoin de garder les valeurs d'identité intactes, je le recommanderais.

Merci à tous ceux qui ont répondu.

2

Je pense que SELECT ... INTO devrait fonctionner avec une colonne IDENTITY. Vous devrez peut-être redéfinir la clé primaire:

SELECT * INTO NewTable FROM OldTable 
GO 
ALTER TABLE NewTable ADD PRIMARY KEY(ColumnName) 

Si cela ne fonctionne pas, vous pouvez générer un script CREATE TABLE pour l'ancienne table, changer le nom pour créer la nouvelle table, puis utilisez IDENTITY_INSERT pour permettre copier les données de clé primaire de la première table en utilisant un INSERT INTO NewTable SELECT FROM OLDTABLE. Ensuite, vous pouvez faire vos autres manipulations sur le serveur en SQL.

Un avantage appréciable est que vous pouvez tester ce script localement ou sur un serveur de test, et le répéter en cas de besoin en relançant le script.

Vos modifications de schéma sont-elles trop complexes pour permettre le changement via le script?

+0

Pouvez-vous donner un exemple d'insert qui combine SELECT ... INTO et IDENTITY_INSERT? – stannius

3

Je pense que vous pouvez être intéressé par Identity Insert

+0

Existe-t-il un moyen d'utiliser Identity_insert avec une technologie d'insertion en masse? L'insertion normale (INSERT INTO ... SELECT) est trop lente pour mes besoins. – stannius

1

S'il vous plaît vérifier ce,

Select * Into NewTable 
From OldTable 
Where 1=2 

Alter Table NewTable 
Add id_col int indentity(1,1) 

insert into NewTable(col1,col2,.....) 
/* do not use id_col */ 
select col1,col2,..... from OldTable 
Questions connexes