J'ai une transaction qui contient plusieurs instructions SQL (INSERT, UPDATE et / ou DELETES). Lors de l'exécution, je veux ignorer les instructions d'erreur en double et continuer avec l'instruction suivante. Quelle est la meilleure façon de faire ça?
Réponses
Trop de publicités?Je pense que vous recherchez l'option IGNORE_DUP_KEY sur votre index. Consultez le site http://sqlkit.com/2009/06/17/ pour une explication.
En élargissant votre commentaire à la réponse de SquareCog, vous pourriez faire:
INSERT INTO X VALUES(Y,Z) WHERE Y NOT IN (SELECT Y FROM X)
INSERT INTO X2 VALUES(Y2,Z2) WHERE Y2 NOT IN (SELECT Y FROM X2)
INSERT INTO X3 VALUES(Y3,Z3) WHERE Y3 NOT IN (SELECT Y FROM X3)
Ici, je suppose que la colonne Y est présente dans les trois tableaux. Notez que les performances seront médiocres si les tables ne sont pas indexées sur Y.
Oh, oui, Y est soumis à une contrainte unique: ils sont donc indexés et cela devrait fonctionner de manière optimale.
Bien que mon catégorique conseil pour vous est de structurer votre sql afin de ne pas tenter de dupliquer les inserts (Philip Kelley est extrait est probablement ce que vous avez besoin), je tiens à mentionner qu'une erreur dans l'énoncé n'est pas nécessairement la cause de la restauration.
À moins d' XACT_ABORT
est ON
, une transaction ne sera pas automatiquement la restauration si une erreur est rencontrée, sauf si elle est suffisamment grave pour tuer la connexion. XACT_ABORT
par défaut est OFF
.
Par exemple, le code sql suivant insère correctement trois valeurs dans la table:
create table x ( y int not null primary key )
begin transaction
insert into x(y)
values(1)
insert into x(y)
values(2)
insert into x(y)
values(2)
insert into x(y)
values(3)
commit
Sauf si vous êtes paramètre XACT_ABORT
, une erreur est levée sur le client et causant de la restauration. Si, pour quelque horrible raison pour laquelle vous ne pouvez pas éviter l'insertion de doublons, vous devriez être en mesure d'intercepter l'erreur sur le client et l'ignorer.
Si par "Ignore Duplicate Error statments", pour abandonner l'instruction en cours et passer à l'instruction suivante sans abandonner la transaction, placez simplement BEGIN TRY .. END TRY autour de chaque instruction:
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH /*required, but you dont have to do anything */ END CATCH
...
Je tiens à carillon avec les éléments suivants: Si 99% de vos données à insérer sans erreur de faire une sélection à l'avance les résultats dans un immense dépôt de performances (comme, dans mon cas, à partir de 200 lignes/sec à 20 lignes/sec dans mon cas) par rapport à la "bête" insère et la capture de l'erreur occasionnelle.
Après avoir ignoré la "Violation de la contrainte de CLÉ PRIMAIRE" erreurs les choses allaient de nouveau à être un goulot d'étranglement par d'autres ressources (marge étant défini comme "ce que le goulet d'étranglement des ressources n'ont pas").
Qui est la raison pour laquelle j'ai atterri sur cette discussion en premier lieu.