Запрос в процедуре PLSQL должен вернуть 1 строку, но вернуть больше строк - PullRequest
0 голосов
/ 13 января 2011


У меня странная проблема с реализацией процедуры pl / sql.
Моя процедура имеет четыре входных параметра varchar и извлекает из таблицы значение id с помощью запроса, подобного следующему:

SELECT ID INTO idvar FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;

В этой таблице name и sur являются уникальными ключами. Поэтому для пары входных параметров (pn, ln) я ожидаю получить только одну строку, но это не так. Действительно, кажется, что обработано только первое условие, а второе - нет.

В моей таблице этот тестовый ряд:

ID | NAME | SUR
1  | JO   | SOME THING
2  | JO   | OTHER ONE
3  | BO   | SOME THING

Если в моей процедуре я сдаю

('JO', 'SOME THING')

Я получаю ID: 1 и 2.
Но если я передам значения

('BO', 'SOME THING')

я получаю только ID 3.

Понятно, что с помощью предыдущего запроса я получил ошибку ORA-01422, поэтому сначала я заменяю ее определением курсора, а затем "for row in (query)":

CURSOR C IS
SELECT ID FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;

Это поведение странно для меня, на самом деле, если я выполняю только запрос из sqlplus или toad, я получаю правильный результат.

Версия Oracle - 8.1.

Заранее спасибо

#

Это моя процедура (надеюсь, вы не найдете несоответствия, потому что я изменил название объектов):

CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
ln in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
) 
AS
  idT    NUMBER;
  idST NUMBER;
  idSE    NUMBER;

  CURSOR C IS 
    SELECT ID
    FROM TABLE T
    WHERE 
    T.NAME = pn AND T.SUR = ln;

BEGIN

     for x in ( SELECT ID
         FROM TABLE T
        WHERE 
        T.NAME = pn AND T.SUR = ln )
     loop 
       DBMS_OUTPUT.put_line('INFOR:' || x.ID);
     end loop;


     open C;
     loop
       fetch C into idT;
        exit when C%NOTFOUND;
        DBMS_OUTPUT.put_line('INLOOP:ID='||idT);
 end loop;
 close C;

 DBMS_OUTPUT.put_line ( 'OUTLOOP: ID='||idT );


  EXCEPTION
    WHEN NO_DATA_FOUND THEN
     NULL;
    WHEN TOO_MANY_ROWS THEN 
      RAISE_APPLICATION_ERROR(-20001, 'Exact Fetch Returned many Rows');  
    WHEN OTHERS THEN
     DBMS_OUTPUT.put_line('ERROR');
     ROLLBACK;
 RAISE;

END myproc;
/

Спасибо

Ответы [ 3 ]

3 голосов
/ 13 января 2011

Может быть, есть конфликт между вашими параметрами и полями таблицы?

Измените его, добавив название вашей процедуры в качестве области действия для ваших параметров:

 T.NAME = myproc.pn AND T.SUR = myproc.ln
2 голосов
/ 13 января 2011

"... потому что я изменил имя объекта"

Возможно, некоторые из ваших параметров имеют те же имена, что и некоторые столбцы.

Например, если ваша процедура выглядела так:

CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
sur in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
)
...
SELECT ID INTO idvar FROM TABLE T WHERE T.NAME = pn AND T.SUR = sur;
...

вы получите ошибку TOO_MANY_ROWS, потому что условие "T.SUR = sur" будет иметь тот же эффект, что и "T.SUR = T.SUR".

2 голосов
/ 13 января 2011

Я проверил ваше первое утверждение с вашей таблицей примеров!И на моей машине это работает.Но это база данных Oracle 10g.

Edit : я переписал вашу процедуру, и на моем компьютере эта версия работает хорошо!

create or replace
PROCEDURE myproc (
  pn in VARCHAR2,
  ln in VARCHAR2,
  other in VARCHAR2,
  datarif in VARCHAR2
) 
AS
  idvar    NUMBER;
BEGIN
  SELECT ID INTO idvar FROM TEST T WHERE T.NAME = pn AND T.SUR = ln;
  DBMS_OUTPUT.put_line ( 'OUTLOOP: ID='||idvar );
END myproc;
...