Курсор Oracle не работает должным образом - PullRequest
1 голос
/ 03 декабря 2010

Вот процедура,

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;

Запрос в cursor извлекает 5 строк, в то время как ожидается 1 строка в соответствии с условиями и значениями аргументов. Тот же самый запрос приводит к 1 строке, когда выполняется независимо. И что удивительно, запрос в cursor всегда возвращает 5 строк независимо от того, выполнено условие c.PERIODE = period AND c.AGENCYNO = agencyNo или нет. Что явно означает, что этот запрос

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;

и этот запрос

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

ведут себя так же внутри cursor. Эта часть AND c.PERIODE = period AND c.AGENCYNO = agencyNo вообще не рассматривается. Есть идеи, что не так?

1 Ответ

5 голосов
/ 03 декабря 2010

Один из ваших параметров имеет то же имя, что и столбец: AGENCYNO.Из-за того, как работает область видимости, это оценивается как 1=1.Вот почему рекомендуется назначать параметрам уникальные имена, например, добавляя к ним p_.

. Вы должны обнаружить, что

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

возвращает нужную одну строку.Строго говоря, вам не нужно менять имя period на p_period, потому что оно уже отличается от periode.Но последовательность является достоинством в разработке программного обеспечения.

...