|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||
|
Inscription : avril 2009 Messages : 13 ![]() |
Bonjour à tous,
Je sais que ce problème a été reporté mainte fois, mais je n'arrive pas à trouver une solution sans pour autant avoir à créer d'autre package ou d'autre trigger, ou une table temporaire.. J'ai le trigger suivant Code :
et un autre trigger qui contient la requête suivante (donc lorsqu'on a un tel insert le premier trigger se déclenche) Code :
je sais que le problème provient du premier count(*) puisqu'il est appliqué sur la table elle même, mais je n'arrive pas à contourner cette erreur Merci pour votre aide |
||||
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Si je ne m'abuse, il faut faire ton select dans une "autonomous transaction", c'est à dire une transaction extérieure à la transaction actuelle. Attention cependant, cela implique qu'elle n'a pas accès aux données que tu es en train de modifier.
|
|
|
00
|
|
|
#3 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Il y a un tutoriel sur le problème de la table mutante sur ce site, mais le meilleur c’est de ne pas utiliser les triggers dans ce cas.
|
|
|
00
|
|
|
#4 | ||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
Comme toujours, que vaudrait votre count(*) dans un environnement multi-users?
Code :
Si vous embarquez dans cette direction en voulant éviter l'erreur de la table mutante en y ajoutant une dose de transaction autonome, vous êtes alors dans une mauvaise direction. |
||
|
|
00
|
|
|
#5 |
|
Inscription : avril 2009 Messages : 13 ![]() |
Je ne comprends pas votre question Mohamed.
je fais actuellement ce count, parce que aprés j'ai des contrôles à faire sur le type de dossier à insérer, certains types devront être unique. Juste une remarque, lorsque je fais un simple insert insert into g_dossier values (....) je n'ai pas le problème de la table mutante. |
|
|
00
|
|
|
#6 | ||
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Citation:
Si la condition est simple et surtout déterministe, alors un FBI (Function Based Indexes) devrait résoudre le problème. Citation:
Mais je pense comme Mnitu et Mohamed que le mieux est d'éviter les triggers dans ce cas, surtout si la contrainte s'exprime facilement. |
||
|
|
00
|
|
|
#7 | ||
|
Inscription : avril 2009 Messages : 13 ![]() |
Merci pour votre réponse skuatamad,
En fait, j'ai deux trigger, c'est dans le premier (table b_organisation) qu'il y'a un insert en masse (INSERT INTO g_dosser ... select * from dbd_type) qui déclenche le deuxième trigger sur la table (g_dosser) , d'ou le count(*) le type de dossier qui doit être unique est comparé en dur genre Code :
comme signalé, si c'est un insert simple je n'ai pas le problème de la table mutante, ceci se déclenche juste avec l'insert en masse. |
||
|
|
00
|
|
|
#8 |
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
Si votre but est d'eviter des doublons de dossiers alors
(a) implémentez une contraint unique sur le dossier ou (b) un index unique (peut-être dans votre case un function based index) Ainsi, vous n'aurez pas à vous souciez du problème de concurrence lorsque deux utilisateurs voudront ajouter le même dossier. Le deuxième attendra la fin du travail du premier avant soit d'être rejeté grâce à (a) ou (b) ou que son insert soit accepté à cause du fait que le premier user a fait un rollback; |
|
|
00
|
|
|
#9 | |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Code :
CREATE UNIQUE INDEX type_chg_uk ON g_dosser (CASE WHEN doss_type <> 'CHG' THEN doss_type ELSE NULL END); Et donc pas de trigger, pas de code, pas d'erreur de table en mutation Il y a des exemples dans la doc sur CREATE INDEX : Citation:
|
|
|
|
00
|
|
|
#10 | ||
|
Inscription : avril 2009 Messages : 13 ![]() |
Merci skuatamad et Mohamed
skuatamad ça aura pu être la solution adéquate si mon trigger se limitait juste à controler les doublons, plus bas dans le trigger j'ai pratiquement le même count qui controle si pour le type 'CHG' on a un champ default_doss_flag a 'Y'. Code :
|
||
|
|
00
|
|
|
#11 | ||
|
Inscription : avril 2009 Messages : 13 ![]() |
Je viens de changer l'insert en masse comme suit, sans pour autant avoir à éradiquer le count de l'autre trigger
Code :
Est ce que ce que j'ai dit est sensé ? |
||
|
|
00
|
|
|
#12 | |||||||
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Pour ce cas :
Code :
Code :
Code :
Regarde ce post pour de plus amples informations : Contraintes complexes ? Citation:
|
|||||||
|
|
00
|
|
|
#13 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 311 ![]() |
Quand vous aurez fini d’écrire vos triggers lisez l’article « The trouble with triggers ».
|
|
|
00
|
|
|
#14 | ||||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 286 ![]() |
Marius m'a précédé concernant l'article de Tom Kyte sur les triggers.
@skuatamad, attention à la valeur null du doss_type lors de la création d'un indexe unique du type fonction comme vous l'avez très justement conseillé. Code :
Code :
|
||||
|
|
10
|
|
|
#15 |
|
Inscription : avril 2009 Messages : 13 ![]() |
Merci à tous !
|
|
|
00
|
|
|
#16 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
|
|
|
00
|
|
|
#17 | |||
![]() ![]() |
Citation:
Code :
CREATE INDEX t1_fbi ON t1(case when v1 <> 'N' then 'X' end)
__________________
Email : http://scr.im/waldar |
|||
|
00
|
|
|
#18 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com