Ma base de données contient trois tables appelées Object_Table
, Data_Table
et Link_Table
. La table de liaison contient juste deux colonnes, l'identité d'un enregistrement d'objet et l'identité d'un enregistrement de données.
Je souhaite copier les données d' DATA_TABLE
où elles sont liées à une identité d'objet donnée et insérer les enregistrements correspondants dans Data_Table
et Link_Table
pour une identité d'objet donnée différente.
Je peux le faire en sélectionnant dans une variable de table et en effectuant une boucle en faisant deux insertions pour chaque itération.
Est-ce la meilleure façon de le faire?
Edit : Je veux éviter une boucle pour deux raisons, la première est que je suis paresseux et une table de boucle / temporaire nécessite plus de code, plus de code signifie plus d'endroits pour faire une erreur et la deuxième raison est un problème de performances.
Je peux copier toutes les données dans une seule insertion, mais comment faire pour que la table de liens soit liée aux nouveaux enregistrements de données où chaque enregistrement a un nouvel identifiant?
la source
Réponses:
Dans une déclaration : Non.
En une seule transaction : Oui
La bonne nouvelle est que le code ci-dessus est également garanti atomique et peut être envoyé au serveur à partir d'une application cliente avec une chaîne SQL en un seul appel de fonction comme s'il s'agissait d'une seule instruction. Vous pouvez également appliquer un déclencheur à une table pour obtenir l'effet d'un seul insert. Cependant, il s'agit toujours de deux instructions et vous ne voulez probablement pas exécuter le déclencheur pour chaque insertion.
la source
insert into ... select ...
déclaration. Comment le code ci-dessus lit-il ou boucle-t-il les données Object_Table. Vous devez toujours utiliser une variable de table que le demandeur n'a pas voulu faire.Vous avez toujours besoin de deux
INSERT
instructions, mais il semble que vous souhaitiez obtenir le àIDENTITY
partir du premier insert et l'utiliser dans le second, auquel cas, vous voudrez peut-être consulterOUTPUT
ouOUTPUT INTO
: http://msdn.microsoft.com/en- us / library / ms177564.aspxla source
Ce qui suit met en place la situation que j'ai eue, en utilisant des variables de table.
Grâce à une autre réponse qui m'a pointé vers la clause OUTPUT, je peux démontrer une solution:
Il s'avère cependant que ce n'est pas si simple dans la vraie vie à cause de l'erreur suivante
Je peux encore
OUTPUT INTO
une table temporaire et ensuite terminer avec un insert normal. Je peux donc éviter ma boucle mais je ne peux pas éviter la table temporaire.la source
On dirait que la table Link capture la relation plusieurs: plusieurs entre la table Object et la table Data.
Ma suggestion est d'utiliser une procédure stockée pour gérer les transactions. Lorsque vous souhaitez insérer dans la table Object ou Data, effectuez vos insertions, récupérez les nouveaux ID et insérez-les dans la table Link.
Cela permet à toute votre logique de rester encapsulée dans un sproc facile à appeler.
la source
Si vous voulez que les actions soient plus ou moins atomiques, je veillerais à les envelopper dans une transaction. De cette façon, vous pouvez être sûr que les deux se sont produits ou que les deux ne se sont pas produits au besoin.
la source
Vous pouvez créer une vue en sélectionnant les noms de colonne requis par votre instruction d'insertion, ajouter un déclencheur INSTEAD OF INSERT et l'insérer dans cette vue.
la source
Je veux insister sur l'utilisation
pour la transaction MSSQL avec plusieurs instructions SQL.
Voir: https://msdn.microsoft.com/en-us/library/ms188792.aspx Ils fournissent un très bon exemple.
Ainsi, le code final devrait ressembler à ce qui suit:
la source
L'insert ne peut fonctionner que sur une seule table à la fois. Plusieurs insertions doivent avoir plusieurs instructions.
Je ne sais pas si vous devez faire le bouclage à travers une variable de table - ne pouvez-vous pas simplement utiliser une insertion de masse dans une table, puis l'insertion de masse dans l'autre?
Au fait - je suppose que vous voulez dire copier les données de Object_Table; sinon la question n'a pas de sens.
la source
Avant de pouvoir effectuer une insertion multitable dans Oracle, vous pouvez utiliser une astuce impliquant une insertion dans une vue sur laquelle un déclencheur INSTEAD OF est défini pour effectuer les insertions. Cela peut-il être fait dans SQL Server?
la source
la source
// si vous voulez insérer le même que le premier tableau
// ou si vous souhaitez insérer certaines parties du tableau un
// Je sais que cela semble trop beau pour avoir raison, mais cela fonctionne et vous pouvez continuer à ajouter des requêtes, il suffit de changer le
J'ai 17 tables dans lesquelles cela a fonctionné.
la source