2010-04-29 25 views
2

J'ai créé une fonction en C# qui me permet de copier un enregistrement et ses enfants apparentés dans un nouvel enregistrement et de nouveaux enfants apparentés dans la même base de données. (Ceci est une application qui permet l'utilisation des travaux antérieurs comme modèle pour un nouveau travail.)Comment puis-je copier un enregistrement SQL ayant des enregistrements associés dans d'autres tables dans la même base de données?

Quoi qu'il en soit, il fonctionne très bien ... Voici une description de la façon dont il accomplit la copie:

Il Remplit table de consultation basée sur la mémoire de deux colonnes avec la clé primaire actuelle de chaque enregistrement. Ensuite, en créant individuellement chaque nouvel enregistrement de copie, il met à jour la table de correspondance avec le PK d'identité du nouvel enregistrement [récupéré à partir de SCOPE_IDENTITY()]. Maintenant, lorsqu'il copie sur des enfants liés, il peut rechercher le nouveau parent PK pour définir le FK sur le nouvel enregistrement. Lors du test, il ne fallait qu'une minute pour copier une structure relationnelle sur une instance locale de SQL Server 2005 Express Edition. Malheureusement, il s'avère terriblement lent dans la production! Mes utilisateurs traitent plus de 60 000 enregistrements par enregistrement parent sur le réseau local vers notre serveur SQL! Alors que ma fonction de copie fonctionne toujours, chacun de ces enregistrements représente une commande SQL UPDATE individuelle et charge le serveur SQL à environ 17% du processeur à partir de son inactivité normale de 2%. Je viens de finir de tester une copie de 50 000 exemplaires et cela a pris presque 20 minutes! Existe-t-il un moyen de dupliquer cette fonctionnalité dans les requêtes SQL ou les procédures stockées pour que le serveur SQL fasse fonctionner l'ensemble de la copie au lieu de la faire exploser sur le réseau local de chaque client?

(Nous courons Microsoft SQL Server 2005 Standard Edition.)

Merci!

-Derek

Répondre

1

Oui il est, si elle est SQL 2005, vous pouvez éventuellement utiliser une procédure stockée CLR pour installer votre code C# dans le Db. Pour faire du TSQL pur, c'est juste une question de temps et d'avoir besoin d'utiliser des variables pour les nouvelles clés. Est-ce juste un cas d'un enregistrement parent et ensuite beaucoup d'enregistrements enfants qui sont seulement dans une table enfant? Vous pouvez potentiellement éviter d'émettre des commandes d'insertion distinctes pour chaque ligne enfant dans ce cas en tirant parti du fait que vous pouvez incorporer une instruction select dans une insertion, en particulier si vous utilisez des colonnes d'identité pour les PK. Ce sera généralement beaucoup plus rapide si vous pouvez le faire. Quelque chose comme cela (la syntaxe peut être un peu loin, mais vous aurez besoin de l'adapter à vos tables réelles de toute façon):

insert into tblchild select @newparentId, col1,col2 from tblChild where [email protected] 

est ici un point de départ sur CLR dans SQL Server ...

http://msdn.microsoft.com/en-us/library/ms131045.aspx (Cet article est SQL 2008, mais une grande partie s'applique probablement).

http://www.sqlteam.com/article/writing-clr-stored-procedures-in-charp-introduction-to-charp-part-1

+0

Merci, Jim! Je viens d'utiliser les fonctions ADO.NET et d'essayer de m'isoler de traiter les procédures stockées le plus longtemps possible. Les procédures stockées CLR ressemblent à la façon de procéder. Malheureusement, la table parente a plusieurs tables enfants, et deux d'entre elles ont une relation 1-à-1 avec une autre table qui utilise leurs PK sur un PK composite, donc j'ai vraiment besoin d'une méthode plus automatisée. Merci encore! -Derek – DerekVS

0

Est-ce que l'aide (code pseudo)

INSERT INTO (PkField, FkField, OtherFields) SELECT NewPkValue, NewFkValue, OtherFields FROM TableName WHERE FkField = OldFkValue 

aide pour les tables enfants connexes en ce sens qu'ils seront plutôt que des mises à jour par lots uniques par dossier?