2010-12-03 5 views
1

Voici la procédure,Oracle curseur ne fonctionne pas comme prévu

CREATE OR REPLACE PROCEDURE provsnXmlCmprsn (
      encyNo SAS_PRO_CTL.AGENCYNO%TYPE, period SAS_PRO_CTL.PERIODE%TYPE) IS 

xmlContent SAS_PRO_XML.XMLCONTENT%TYPE; 
sasProvisionId SAS_PRO_CTL.SASPROVISIONID%TYPE; 

CURSOR crsrXml IS 
SELECT XMLCONTENT, c.SASPROVISIONID FROM SAS_PRO_XML x, SAS_PRO_CTL c 
    WHERE x.SASPROVISIONID = c.SASPROVISIONID AND c.PERIODE = period 
            AND c.AGENCYNO = agencyNo ORDER BY XMLLINENO; 

BEGIN 
DBMS_OUTPUT.put_line('Params: ' || agencyNo || ', ' || period); 

OPEN crsrXml; 
LOOP 
    FETCH crsrXml INTO xmlContent, sasProvisionId; 
    EXIT WHEN crsrXml%NOTFOUND; 
    DBMS_OUTPUT.put_line('XML Content Length: ' || LENGTH(xmlContent)); 
END LOOP; 
CLOSE crsrXml; 

END provsnXmlCmprsn; 

La requête dans le cursor récupère 5 lignes, alors que 1 ligne est prévu, selon les valeurs de l'état et des arguments. La même requête résulte en 1 ligne, lorsqu'elle est exécutée indépendamment. Et la partie surprenante est, la requête dans le cursor toujours retourner 5 lignes, peu importe si la condition, c.PERIODE = period AND c.AGENCYNO = agencyNo, passé ou non. Ce qui signifie clairement que cette requête,

SELECT XMLCONTENT, c.SASPROVISIONID FROM SAS_PRO_XML x, SAS_PRO_CTL c 
    WHERE x.SASPROVISIONID = c.SASPROVISIONID AND c.PERIODE = period 
            AND c.AGENCYNO = agencyNo ORDER BY XMLLINENO; 

et cette requête,

SELECT XMLCONTENT, c.SASPROVISIONID FROM SAS_PRO_XML x, SAS_PRO_CTL c 
    WHERE x.SASPROVISIONID = c.SASPROVISIONID ORDER BY XMLLINENO; 

se comportent même à l'intérieur du cursor. Ceci, AND c.PERIODE = period AND c.AGENCYNO = agencyNo, une partie n'est pas du tout considérée. Une idée de ce qui ne va pas?

Répondre

5

L'un de vos paramètres porte le même nom que la colonne: AGENCYNO. En raison de la façon dont la portée fonctionne, cette valeur est 1=1. C'est pourquoi il est recommandé de donner des noms uniques aux paramètres, par exemple en les remplaçant par p_.

Vous devriez trouver que

AND c.PERIODE = p_period AND c.AGENCYNO = p_agencyNo 

renvoie le choix d'une ligne. Strictement parlant, vous n'avez pas besoin de changer le nom de period en p_period car il est déjà distingué de periode. Mais la cohérence est une vertu dans l'ingénierie logicielle.

+0

APC m'a battu à elle. Il est apparemment beaucoup plus caféiné que moi en ce moment. –

+2

@JustinCave - en fait, le premier thé de la journée se refroidit sur la table;) – APC

Questions connexes