• ベストアンサー

[Oracle9i]PL/SQLでFETCHしても、%FOUND=TRUEにならない

簡単なことだと思うのですが、はまってしまったので質問させてください。 以下のようなコードがあります。PL/SQLで書いてます。 SELECTした内容をFETCHして、IF文の%FOUNDで処理内容を変えているのですが、%FOUND=FALSEで必ず返ってきています。SELECT文自体でデータはひっぱって来ている(別で流しました)ようなので、理由が全然わからずまいってます。 -------------------------------------------------- FUNCTION get_siten_cd(siten_cd varchar2) RETURN varchar2 IS ret_siten_cd varchar(4); --4桁支店コード /*カーソル定義*/ CURSOR cs is SELECT SITEN_CD FROM MEI1.SITEN_MST WHERE SITEN_CD3 = siten_cd; /**カーソルに基づくレコードの定義**/ rs cs%ROWTYPE; BEGIN OPEN cs; FETCH cs INTO rs; IF cs%FOUND THEN --データが存在する場合 ret_siten_cd := rs.SITEN_CD; ELSE --データが存在しない場合 ret_siten_cd := NULL; END IF; CLOSE cs; RETURN ret_siten_cd; END; -------------------------------------------------- よろしくお願いします。

  • aw11
  • お礼率68% (30/44)
  • Oracle
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • jmh
  • ベストアンサー率23% (71/304)
回答No.3

列名(SITEN_CD)と引数(siten_cd)が同じ名前だからかも。

aw11
質問者

お礼

正解ですw。 ってか、ダメなんですねこれ。知りませんでした。 なんたか自分で解決しました。 皆さん回答ありがとうございましたっ!

その他の回答 (2)

回答No.2

こんばんは。 Functionの引数の「siten_cd」には、ちゃんと値が入っていますか? SQLが行セットを返していないのが原因と思われますが・・・。 %ROWCOUNTは取れますか? 取れているならFETCHした時点で「rs」の中に入っているはずなので、dbms_output.put_lineで表示してみてください。 IF文の問題ではないと思いますよ。 (^^ゞ

aw11
質問者

お礼

回答ありがとうございます。 皆さんの言われたことほとんどやってました。 SQLも別で流してますし、dbms_output.put_lineも使って変数の中身やら表示してました。ちょっと説明が足りませんでした。すみません。 ただ、どうしてもSQLの結果が取れてなくて。 オラクルマスターのプラチナ持ってる人も知らなかったみたいですw。

回答No.1

文法的に間違いはないと思います。そうなるとあとは、やはりSelectで1行も取得できていないという事になります。 実際に見えないところを疑うしかないのですが、siten_cdにはきちんと値が入っているのでしょうか。 あるいはrs.SITEN_CDには値は入っていないですか?(つまりFOUNDはFalseだけれど、実は成功しているパターン。あり得ないか・・・) あとはcs%NOTFOUNDを使ってIF文を書き直してみるか・・・ すみません、考え付く限り書いてしまいました。何かのヒントにでもなればと思います。

aw11
質問者

お礼

回答ありがとうございますっ! 上にも書いてありますが、なかなか意外?なミスでした。

関連するQ&A

  • PL/SQLのカーソルについて

    すみません。 PL/SQLにて以下のようなカーソルがあるのですが、 引数のpJYOKENをWHERE条件に追加することはできないでしょうか。 pJYOKENには(属性 = 0)のような条件が入っています。 条件はその都度違ったものが入ってくるイメージです。 cursor CURテスト (pJYOKEN IN VARCHAR2) IS SELECT 社員コード FROM テストマスタ WHERE 会社ID = '001' AND 区分 = 1; rcテスト CURテスト%rowtype; よろしくお願い致します。

  • PL/SQLでカーソルを指定する方法

    以下のSQL文で、 あるストアドプロシージャを作成し、その引数の値を WHERE句の検索条件に取ってカーソルを宣言したいので すが、どうやってもエラーが出ます。結果として カーソルで格納したデータを呼び出し元に返したいの ですが…。下記の文は間違ってますか? CREATE OR REPLACE PROCEDURE ss( quote IN NUMBER result OUT CHAR ) IS CURSOR cur IS SELECT empname FROM emp WHERE empno = quote; result cur%rowtype; BEGIN OPEN cur; LOOP FETCH cur INTO result; ~ END; どうかよろしくお願いします。

  • PL/SQLプログラムの書き方がわかりません。

    「課題」2つのデータベースがあり、それぞれ別インスタンス。A―DBからB―DBに、データを抽出し、もっていきます。このとき、キーとなるデータが、Bに既にある場合は、UPDATEを、ない場合はINSERTします。 プログラムの流れは、LOOP FETCH でAから取り出すSELECT文につけられたカーソルを実行し、次に SELECT文で、Bからキーとなるデータがあるか検索して、それで、IF文で、なかったときは、INSERT、あるときはUPDATE だと思うのですが・・・書き方がいまいちわかりません。どなたか、サンプルになるようなプログラムがございましたら、教えていただけませんでしょうか?まったくの素人なのですが、この課題をしなければいけません。よろしくお願いします。

  • 【PL/SQL】LOOPした動的SQLにてFETCHができない

    OracleのPL/SQLで FOR .. LOOP内にて動的SQLを使い SELECTしてきた値を順次FETCHして配列に格納していきたいのですが、 LOOPの1件目のみFETCHがされて2件目以降は全てNULLになってしまいます。SQL文は間違っていません。DBMS_SQL.LAST_ROW_COUNTで1件以上の検索結果があることも確認済みです。 なぜでしょう?教えて下さい! EXECUTE IMMEDIATEをLOOP内で使うことに問題あり? 簡略化した例です。p_noにはすでに文字列格納済みと見てください。 txtsql VARCHAR2(1000); -- 動的SQL mkin INTEGER; fornum1 INTEGER; max_count INTEGER; -- ループされる最大件数 TYPE type_mkin IS TABLE OF NUMBER(10) INDEX BY BINARY_INTEGER; TYPE type_pno IS TABLE OF CHAR(10) INDEX BY BINARY_INTEGER; mkin type_mkin; p_no type_pno; BEGIN FOR fornum1 IN 1 .. max_count LOOP txtsql := 'SELECT SUM(TPSV_NO) ' || ' FROM ACTV || ' WHERE PRI_NO= ' || p_no(fornum1); EXECUTE IMMEDIATE txtsql INTO mkin(fornum1); DBMS_OUTPUT.PUT_LINE(mkin(fornum1)); END LOOP; END;

  • 【PL/SQL】SQL文が長すぎてSELECTできない

    oracle9iのpl/sqlでSELECT文を発行し 取得したカーソルを返す処理をしています。 where句が動的になる為 実行するSQL文が長くなり ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。が発生しました のエラーが発生します。 そこで、SQL文の部分をCLOB型にしたり SQL文を「||」でつなげたり してみましたが、どちらもエラーになりました。 長すぎるSQL文を実行するには どうしたらよいでしょうか? 以下ソースです。(左側の数字は行数です) ----------------------------------- 1 PROCEDURE テスト(O_カーソル IN OUT 情報カーソル) IS 2 TYPE curType IS REF CURSOR; 3 tmpCur curType; 4 sqlStr VARCHAR2(32767); 5 6 7 BEGIN 8 9 sqlStr := 'SELECT ' 10 sqlStr := sqlStr || 'A,B ' 11 sqlStr := sqlStr || 'FROM' <<省略>> 12 OPEN tmpCur FOR sqlStr ←エラー発生 13 O_カーソル := tmpCur; --取得したカーソルを返す 14 END テスト; ----------------------------------- (1)SQL文をCLOB型にしてみる:コンパイルエラー 4 sqlStr CLOB (2)SQL文を「||」でつなげてみる:文字列バッファが小さすぎますでエラー Dim sqlStr1 VARCHAR2(32767); Dim sqlStr2 VARCHAR2(32767); Dim sqlStr3 VARCHAR2(32767); <<省略>> 12 OPEN tmpCur FOR (sqlStr1      || sqlStr2      || sqlStr3 <<省略>> )

  • PL/SQLのプロシージャ間でカーソル?の受渡

    PL/SQLのプロシージャ間でカーソル?の受渡 お世話になります。 親でループ対象とするカーソルを、子プロシージャで生成し 親に戻すということは可能でしょうか。 うまく伝わりにくいかと思いますので、下記にVBで行った例を記します。 親----------------------- Sub aaa()   Dim rs As New ADODB.Recordset    Call bbb(rs)    Do Until rs.EOF      Debug.Print rs!COLUMN1      rs.MoveNext    Loop End Sub 子----------------------- Function bbb(ByRef rs As ADODB.Recordset)  rs.Open "SELECT * FROM TABLE1", CurrentProject.Connection End Function 以上、お願い致します。

  • dbからデータをとりだす際、sqlのfetch結果をjavaでとりだす

    dbからデータをとりだす際、sqlのfetch結果をjavaでとりだすのは可能なのでしょうか? (チェックボックス 空欄) sql (チェックボックス 空欄) begin; declare cursor_name cursor for select * from user_ad; fetch forward 3 from cursor_name; //この結果をjavaでとりだしたい 注:この後、PostgreslqMyAdminで表そうとしたら、commitしたら表せない!! ふつうに、select文でとりだすなら分かるのですが。。。 con = Connectionのこと 処理ソースは、、、 必要最小限な部分だけ、記述しています。 PrepareStatement stmt = null; try { String sql = "select user_id from user_ad"; this.stmt = con.prepareStatement(sql); //ループでデータとりだし ResultSet rs = stmt.executeQuery(); while(rs.next()) { String userId = rs.getString("user_id"); } }catch(Exception e) { System.out.println(e.getMessage()); System.out.println(e.getStackTrace()); } fetchでとりだそうとすると、カーソルが関係していて、処理自体、変わってくるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • PL/SQLでの処理について

    キーの異なる2つのトランザクションテーブルA,Bに マスタCの値を引っ張ってきて各A,B埋める処理を、テーブル名を引数にPL/SQLのプロシージャにしたいのですが、良い方法はありますか? 以下のイメージです。 <TABLE A> KEY_A C_CD C_VALUE -----+----+------- 1 3 2 3 3 1 <TABLE B> KEY_B C_CD C_VALUE -----+----+------- 1 3 2 3 3 1 <TABLE C> C_CD C_VALUE ----+-------- 1 A 2 B 3 C SQL>EXECUTE foo('A'); <TABLE A> KEY_A C_CD C_VALUE -----+----+------- 1 3 C 2 3 C 3 1 A SQL>EXECUTE foo('B'); <TABLE B> KEY_B C_CD C_VALUE -----+----+------- 1 3 C 2 3 C 3 1 A <処理イメージ> CREATE OR REPLACE PROCEDURE FOO(TNAME VARCHA2) IS c_cd NUMBER; C1 INTEGER; SQL1 VARCHAR2(2000); I INTEGER; BEGIN SQL1 := 'SELECT c_cd FROM ' || tname; C1 := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(C1, SQL1, DBMS_SQL.V7); DBMS_SQL.DEFINE_COLUMN(C1, 1, c_cd); LOOP IF DBMS_SQL.FETCH_ROWS(C1) > 0 THEN DBMS_SQL.COLUMN_VALUE(C1, 1, c_cd); UPDATE tname set value = c_cd; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ↑ここの部分をうまくかけないでしょうか? ELSE EXIT; END IF; END LOOP; end /

  • PL/SQL-プロシージャ

    プロシージャBはテスト実行のため、プロシージャAを真似て作成しています。 --最後のIF文で、プロシージャAかBのどちらかに走らせたいと思っています。 DECLARE --プロシージャA--------------------------------------- PROCEDURE A IS fno1 utl_file.file_type; dnm1 varchar(200) :='XXX'; fnm1 varchar2(200) :='BBB.txt'; CURSOR cu1 is select XYZ as ABC from CCC; BEGIN fno1 := utl_file.fopen(dnm1,fnm1,'w'); FOR CU1_REC1 in CU1 loop utl_file_put_line(fno1,' '|| CU1_REC1.XYZ END LOOP; utl_file.fclose(fno1); end; --プロシージャB------------------------------------- プロシージャAと似たような処理 --プロシージャAかBかを判定するIF文------------------------------ BEGIN IF CCC.ABC = '0'; THEN A; ELSE B; ENDIF; END; /

  • 【PL/SQL】CURSOR ・・・ IS SELECT・・・FOR UPDATE が機能しない

    カーソルの宣言で、FOR UPDATE を指定しているのに、 WHERE CURRENT OF での更新が効きません。 エラーは発生せず、全件分ループも回っているのですが、値がまったく書き換わっていません。 Oracle Ver. = Oracle8i Release 8.1.6.0.0 CREATE OR REPLACE FUNCTION TEST_FNC RETURN BOOLEAN IS todofu_cd NUMBER(2) := 0; strSQL VARCHAR2(2000) := ''; CURSOR cur IS SELECT * FROM TEST_TBL FOR UPDATE; BEGIN For cur_rec In cur Loop DECLARE BEGIN SELECT TODOFU_CD INTO todofu_cd FROM M_POST WHERE POST_NO = cur_rec.POST_NO; EXCEPTION When NO_DATA_FOUND Then todofu_cd := 0; END; UPDATE TEST_TBL SET TODOFU_CD = todofu_cd WHERE CURRENT OF cur; COMMIT; End Loop; EXCEPTION  (省略) END; / 「CURSOR cur IS SELECT * FROM TEST_TBL FOR UPDATE;」の部分は、 「CURSOR cur IS SELECT POST_NO, TODOFU_CD FROM TEST_TBL FOR UPDATE OF TODOFU_CD; 」と記述しても結果は同じでした。 上書きしようとしている値である「todofu_cd」にきちんと望む値が格納されていること、ループが正常に回り、各行にアクセスしていることは、確認済です。 原因が分かる方がいらっしゃいましたらご教授下さい。 また、質問の内容に不備があるようでしたら、ご指摘下さい。 以上、どうかよろしくお願い致します。