samedi 30 octobre 2010

ORA-01427 lors d'un update-select

Un développeur est venu me voir hier car l'update qu'il essayait d'exécuter lui retournait l'erreur suivante:
Erreur ORA-01427 single-row subquery returns more than one row

L'update en question était le suivant:
update refech e set daech=(
select distinct m.action_date 
from maturities m where m.ubix_contract_code=e.corex 
and m.cmech=e.cmech and m.caech=e.caech 
and m.action in ('LTD','XD')
) 
where e.corig='FOW';

Le développeur avait bien compris que l'erreur était dû au fait que la clause select dans l'update retournait plus d'une ligne pour un match dans la table REFECH mais n'arrivait pas à identifier ces doublons.
Voici la requête qui permet ici d'avoir les lignes dans la table MATURITIES qui retournent plus d'une ligne dans la jointure avec REFECH effectuée dans l'update:

select count(1), m.ubix_contract_code,e.corex, m.cmech,
e.cmech,m.caech,e.caech 
from maturities m, refech e 
where m.ubix_contract_code=e.corex and m.cmech=e.cmech 
and m.caech=e.caech and m.action in ('LTD','XD')
and e.corig='FOW' 
group by  m.ubix_contract_code, e.corex, m.cmech,
e.cmech,m.caech,e.caech 
having count(1)>1

Le principe ici consiste à joindre les 2 tables selon les critères utilisés dans l'update et de regrouper les lignes selon ces critères en n'affichant que les lignes ayant plus d'une occurrence.

Une fois les doublons récupérés il est facile de régler le problème (suppression des doublons, ajout d'une clause de jointure oubliée etc.)