2011-01-13 78 views
0


我有執行的PL/SQL程序一個奇怪的問題。
我的程序有四個VARCHAR輸入參數,並提取從表id值與這樣的查詢:查詢手續PLSQL必須返回1行,但返回更多的行

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

在此表中,姓名和河畔是唯一的關鍵。所以對於一對輸入參數(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,所以我先用遊標定義代替它,而「在(查詢)行」之後:

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

這種行爲很奇怪,我,事實上,如果我只是從sqlplus或蟾蜍執行查詢,我會得到正確的結果。

的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

你能否提出完整的程序和程序的調用(與上下文)? – Tim 2011-01-13 09:45:12

+0

我在原帖上寫手續。 – sangi 2011-01-13 10:16:13

回答

3

也許你的參數和表格的字段之間有衝突?

更改它加入你的程序的名稱,範圍爲您的參數:

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

添加範圍似乎是解決方案。非常感謝你。 – sangi 2011-01-13 10:47:00

2

我與你的示例表測試了第一個發言!在我的機器上它工作。但那是一個Oracle 10g數據庫。

編輯: 我重新編寫了你的​​程序,在我的機器上該版本運行良好!

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

添加ROWNUM = 1不是很好的建議。如果查詢在不應該時返回多行,則可能表示編碼錯誤(這似乎是每個接受的答案的情況)。所以簡單地通過「隨機」選擇其中一行來處理它並不是一個好的解決方案。 – 2011-01-13 14:55:20

2

「......因爲我的對象改名」

也許你的一些參數具有相同的名稱爲一些列。

例如,如果你的程序是這樣的:

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 =河畔」將具有相同的效果「T.SUR = T.SUR」 。