Conseils et formations : vos deux atouts pour réussir !
Accueil > DBA > Messages > Transfert de données et Pk
Transfert de données et Pk

Position du problème :


Vous cherchez à transférer des données entre deux bases SQL Server, mais souhaitez respecter les contraintes de clés primaires lors de ces transferts.
Vous êtes donc confrontés à ce type de problème :

Si un CLUB de course à pied est défini sur une LIGUE on a une Foreign key entre le club et sa ligne et il faut donc insérer d'abord les données des ligues et ensuite les données des clubs.
Exemple de données :
LIGUE :
H-N Haute Normandie
CLUB
1234 Stade Dieppois H-N
4321 Sports Loisirs Aliermontais H-N

Ce problème se répète de manière récursive si on a des coureurs enregistré sur des clubs..
Une foreign key du coureur pointe sur le CLUB; et l'ordre final des tables sera donc
LIGUE
CLUB
COUREUR

Comment généraliser et automatiser tout cela ?

Utilisation des vues du système :


Nous allons pour ce faire utiliser deux vues sur les tables et objets du systèmes :

sys.foreign_keys qui nous donne les couples (référenceur, référencé)

et
INFORMATION_SCHEMA.TABLES qui nous donne les noms des tables utilisateur
voyons ces deux vues en exécution :


    select name as NomContrainte,

    object_name(parent_object_id) as Referenceur,

    object_name(referenced_object_id) as Reference

    from sys.foreign_keys

 

 

......
    select table_NAME from INFORMATION_SCHEMA.tableS

    where table_TYPE = 'BASE table'

 

 

.....

Corps de l'algorithme :


Le principe de l'algorithme est le suivant :

on cherche des tables qui ne sont pas référencées par d'autres et on les supprime de la liste des tables à traiter.
On continue ce process jusqu'à l'une des conditions :

- le nombre de tables à traiter est arrivé à 0
- le nombre de tables à traiter ne diminue plus, ce qui peut se produire dans les cas suivants : récursivité sur des références, self-référence,...

L'algorithme est donc perfectible : à vos claviers...

Code source complet :


    set nocount on

 

    declare @tablesATraiter table (Nomtable sysname)

    declare @tablesHierarchisees table (Nomtable sysname, NoOrdre int identity(1,1))

    declare @iResteATraiter int

    declare @iResteATraiterPrec int

 

 

    -- A priori nous traitons toutes les tables de la base

    insert into @tablesATraiter

    select table_NAME from INFORMATION_SCHEMA.tableS

    where table_TYPE = 'BASE table'

 

 

    set @iResteATraiterPrec = -1

    select @iResteATraiter = count(*) from @tablesATraiter

    while 1=1

    begin

    if @iResteATraiter < 1

    break -- on a fini

 

    if @iResteATraiterPrec = @iResteATraiter

    break -- on ne peut plus évoluer

 

    print 'Il reste ' + str(@iResteATraiter) + ' tables à traiter '

 

 

    -- Affichage de test éventuel si pb :

    -- select Referenceur.Nomtable,name,Reference.Nomtable

    -- from @tablesATraiter Referenceur inner join sys.foreign_keys FK

    -- on Referenceur.Nomtable = object_name(FK.parent_object_id)

    -- inner join @tablesATraiter Reference

    -- on object_name(FK.referenced_object_id) = Reference.Nomtable

 

 

    -- Trouver celles qui ne référencent aucune des tables restant à traiter

    insert into @tablesHierarchisees

    select Nomtable from @tablesATraiter

    where Nomtable not in (

    select Referenceur.Nomtable

    from @tablesATraiter Referenceur inner join sys.foreign_keys FK

    on Referenceur.Nomtable = object_name(FK.parent_object_id)

    inner join @tablesATraiter Reference

    on object_name(FK.referenced_object_id) = Reference.Nomtable )

 

    select * from @tablesHierarchisees

 

 

    delete from @tablesATraiter

    where Nomtable in (select Nomtable from @tablesHierarchisees)

 

    set @iResteATraiterPrec = @iResteATraiter

    select @iResteATraiter = count(*) from @tablesATraiter

 

    end

 

    print 'Il reste ' + str(@iResteATraiter) + ' tables à traiter '

    select * from @tablesATraiter

 

    print 'Résultat de la hiérarchie : '

    select * from @tablesHierarchisees

 

Vérification de l'exécution :


 


Commentaires : comme indiqué, si des self références ont été définies, l'algorithme ne peut traiter la table en question :
cela sera de toute façon délicat
qui a commencé l'œuf ou la poule ??

Conclusion


Ce morceau de code est un préalable à des traitements plus sérieux, il reste bien sûr à compléter avec les copies de votre choix :
insert select,
bulk insert
ligne à ligne
....
Utilisation de SSIS
....

le principe étant de le faire dans l'ordre des clés primaires.

Commentaires

Aucun commentaire sur ce message.