开发者

Query in Procedure PLSQL must return 1 row, but return more rows

开发者 https://www.devze.com 2023-02-03 19:46 出处:网络
I have a strange problem implementing pl/sql procedure. My procedure has four varchar input parameter, and extracts from a table an id value with a query like this:

I have a strange problem implementing pl/sql procedure.

My procedure has four varchar input parameter, and extracts from a table an id value with a query like this:

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

In this table, name and sur are unique key. So for a couple of input parameter (pn,ln), I expect to obtain only one row, but isn't so. Indeed, it seems that only the first condition processed, and the second doesn't.

In my table I have, this test row:

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

If in my procedure I pass

('JO', 'SOME THING')

I obtain ID: 1 and 2.

But if I pass values

('BO', 'SOME THING')

i obtain only ID 3.

Clearly, with previous query I obtained error ORA-01422, so I substitute it with a cursor definition first, and a "for row in (query) " later:

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

This behavior is strange for me, in fact if I exec only query from sqlplus or toad, i obtain correct result.

Oracle version is 8.1.

Thanks in advance

#

This is my procedure (I Hope you don't find mismatch, because I changed name of objects):

CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
ln in开发者_StackOverflow社区 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;
/

Thank you


Maybe there's a clash between your parameters and fields of the table?

Change it by adding the name of your procedure as scope for your parameters:

 T.NAME = myproc.pn AND T.SUR = myproc.ln


"... because I changed name of objects"

Maybe some of your parameters have the same names as some columns.

For example if your procedure looked like this:

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;
...

you would get TOO_MANY_ROWS error because the condition "T.SUR = sur" would have the same effect as "T.SUR = T.SUR".


I tested your first statement with your example table! And on my machine it works. But that is an Oracle 10g database.

Edit: I re-writed your procedure and on my machine that version works well!

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;
0

精彩评论

暂无评论...
验证码 换一张
取 消