2011-01-13 7 views
0


pl/sqlプロシージャの実装に奇妙な問題があります。
私の手順は、4つのvarchar型の入力パラメータがあり、このようなクエリでテーブルから抽出id値:この表でプロシージャ内の問合せPLSQLは1行を戻す必要がありますが、さらに多くの行を戻す必要があります

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

、名前とSURは、一意のキーです。だから、いくつかの入力パラメータ(pn、ln)に対して、私は1つの行だけを得ることを期待しますが、そうではありません。 実際、最初の条件だけが処理され、2番目の条件は処理されないようです。私は私のテーブルで

、この試験行:

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

私の手順でIは

('JO', 'SOME THING') 

を渡した場合、私はID得る:1,2
をしかし、私は値を渡す場合

('BO', 'SOME THING') 

私はID3を取得します。

は明らかに、前のクエリで私は、エラー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

+0

元の投稿に手続きを書いています。 – sangi

答えて

3

ありがとうあなたのパラメータとテーブルのフィールドとの間に衝突がありますか?あなたのパラメータの範囲として、あなたのプロシージャの名前を追加することにより、

変更を:

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

スコープを追加することが解決策であるようです。どうもありがとうございました。 – sangi

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を追加することはあまり良いアドバイスではありません。クエリが複数の行を返してはならない場合、それはおそらくコーディングのエラーを示します(これは受け入れられた回答ごとにそうであるようです)。だから、単純に「ランダムに」行の1つを選択して作業することは、良い解決策ではありません。 –

+0

@Dave Costa:あなたはそうです!私は汚れた溶液を取り除いた。しかし時々テストのために私は再びそれを使用します...;) – Tim

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

条件「T.SURは=シュル」は「T.SUR = T.SUR」と同じ効果がありますので、あなたがTOO_MANY_ROWSエラーになるだろう。

+0

確かに、そうです!!!ありがとう – sangi

関連する問題