カーソルフェッチにて、最終レコードが重複します

このQ&Aのポイント
  • WindowsVista Oracle10gの環境で、カーソルフェッチを使用してPL/SQLを実行しましたが、最終レコードが重複してしまいます。
  • SQLPlusでの確認では正しく返ってくるため、問題はSQL文自体ではなさそうです。
  • 最終レコードが重複する原因がわからず、解決策を求めています。ご教授いただけると幸いです。
回答を見る
  • ベストアンサー

カーソルフェッチにて、最終レコードが重複します

いつもお世話になります。 WindowsVista Oracle10gの環境にて、以下のようにPL/SQLを作成し、結果を確認しましたが、最終レコードが重複してしまいます。 SQL文が悪いのかと思い、切り出してSQLPlusで確認しましたが正しく返ってきます。 DECLARE type cur_type is ref cursor; souk_cur cur_type; vSql varchar2(2000); BEGIN vSql := ' select ~ from TableA' open souk_cur for vSql; loop fetch souk_cur into p1; dbms_output.putline(p1) exit when souk_cur%notfound; end loop; close souk_cur; END; / <結果> 1 あああ 2 いいい 3 ううう 3 ううう 試しにorder byで並べ替えると、 <結果> 3 ううう 2 いいい 1 あああ 1 あああ と、やはり最終レコードが重複します。 どなたかご存知の方おられましたらご教授願えませんでしょうか? 宜しくお願い致します。

  • Oracle
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

>EXITをLOOPの直後に持ってきましたが結果は同様でした。 FETCHの後じゃないと意味ないです。 loop fetch souk_cur into p1; exit when souk_cur%notfound; dbms_output.put_line(p1); end loop; close souk_cur; END;

その他の回答 (1)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

単にDBMS_OUTPUTの場所が悪いだけです。 カーソルが空になったかどうか評価する前に書き出しているから、カーソルが空になっても1回書いてしまっています。 EXIT文が先にあるべきです。

ryozyryozy
質問者

お礼

ご回答ありがとうございます。 最初はそのように思い、EXITをLOOPの直後に持ってきましたが結果は同様でした。 他に考えられることはありませんでしょうか? 再度、こちらでも確認してみます。

関連するQ&A

  • VBからストアドの動的SQLを呼んで値をレコードセットで取得する方法

    お世話になります。 VBからストアドの動的SQLを呼んで、VB側で値をレコードセットで取得する方法を探しています。 ■ストアド CREATE OR REPLACE PACKAGE SAMPLE as CURSOR c2 IS select A from TBL; TYPE TANTOYOSANDATA IS REF CURSOR RETURN c2%ROWTYPE; PROCEDURE GetNUMBER(C IN NUMBER,           CU OUT TANTOYOSANDATA); end; / -- CREATE OR REPLACE PACKAGE BODY SAMPLE IS PROCEDURE GetNUMBER(C IN NUMBER,             CU OUT TANTOYOSANDATA) IS CUR INTEGER; STATUS INTEGER; ROW_PROCESSED INTEGER; A NUMBER; BEGIN --カーソルをOPENする CUR :=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(CUR,'SELECT A FROM TBL ',DBMS_SQL.V7); DBMS_SQL.DEFINE_COLUMN(CUR,1,A); ROW_PROCESSED :=DBMS_SQL.EXECUTE(CUR); STATUS :=DBMS_SQL.FETCH_ROWS(CUR); WHILE (STATUS <> 0) LOOP DBMS_SQL.COLUMN_VALUE(CUR,1,A); STATUS :=DBMS_SQL.FETCH_ROWS(CUR); END LOOP; END; END SAMPLE; / ■VB側 Set GoORASESSION = CreateObject("OracleInProcServer.XOraSession") Set GoORADATABASE = GoORASESSION.OpenDatabase(dbname, cnuser, ORADB_DEFAULT) Set Recordset = GoORADATABASE.CreatePLSQLDynaset("Begin SAMPLE.GetTANTOINFO(1,:CU)); end;", "CU", ORADYN_DEFAULT) ' If Recordset.EOF Then Do While Not Recordset.EOF Label11.Caption = Recordset(0) Recordset.movenext  Loop 復帰値をRecordSetで受けて それをまわしながら1レコードずつ取得する方法を探しています よろしくお願いします。

  • PL/SQLの動的SQLで複数の項目を取得する方法教えて下さい。

    動的SQLで複数の項目を取得する方法で 悩んでいます。 下記の例だと、1項目しか取れません。 何か他のやり方でもいいので、複数の項目を 取得する方法を教えていただきたいです。 ********************************************* declare sql_stmt varchar2(200); wk_grp varchar2(5); wk_name varchar2(30); type cursor_type is ref cursor; cur_name cursor_type; begin wk_grp := '1u'; open cur_name for 'select 名前 from 社員表 where 所属グループ = :v1' using wk_grp; loop fetch cur_name into wk_name; exit when cur_name%notfound; dbms_output.put_line(wk_name); end loop; close cur_name; end; ********************************************* 下記のようなDBMS_SQLパッケージ?? を利用した方法がいいんでしょうかね。。。。 DBMS_SQL.COLUMN_VALUE(SQL,1,WK_NAME) DBMS_SQL.COLUMN_VALUE(SQL,2,WK_NO) よくわかってないので、宜しくお願いします。

  • 不要なwhere文が混じった重複レコードのカウント

    下記のSQL文があります。 tableA内で、tableA.id(A.id)は重複があります。 tableA内でのtableA.id(A.id)の重複レコード数をcount関数などでSELECTしたいのですが、 下記SQL文からどのように付け加えたらいいのか、お分かりの方いますでしょうか? SELECT A.id as id, A.xxx as xx, A.yyy as yy, B.zzz as zz FROM tableA A, tableB B WHERE A.id = B.id AND A.xxx = x AND A.yyy = y なお、「A.yyy = y」という条件は、tableA.idの重複レコード数をカウントする上で必要な条件なのですが、 「A.xxx = x」という条件は、tableA.idの重複レコード数をカウントする上で、不要な条件です。 以上、よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • 動的なSQLからカーソルを返す。

    下記のようなカーソルを返すパッケージがあったとします。 CREATE OR REPLACE PACKAGE TEST AS CURSOR C1 IS SELECT * FROM テーブル; TYPE TC1 IS REF CURSOR RETURN C1%ROWTYPE; PROCEDURE P_TEST(in条件 IN CHAR, CU OUT TC1); END; CREATE OR REPLACE PACKAGE BODY TEST IS PROCEDURE P_TEST(in条件 IN CHAR, CU OUT TC1) AS sqlStr VARCHAR2(1000); cur NUMBER; r NUMBER; BEGIN cur := DBMS_SQL.OPEN_CURSOR; sqlStr := 'OPEN CU FOR SELECT * FROM テーブル WHERE 条件 = ' || in条件; DBMS_SQL.PARSE(cur, sqlStr, DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN(cur, 1, CU); r := DBMS_SQL.EXECUTE(cur); DBMS_SQL.CLOSE_CURSOR(cur); END; SELECTした結果のカーソル(CU)をクライアントで取得したいのですけど 技術的に可能でしょうか? ストアドのコンパイル時に→DBMS_SQL.DEFINE_COLUMN(cur, 1, CU);が エラーとなります。 DBMS_SQL.DEFINE_COLUMNではカーソルタイプは取得できないとわっかたの ですがカーソルを取得する為のDBMS_SQL.DEFINE_COLUMNにかわる DBMS_SQL.?????はないでしょうか? いろいろ調べたのですが手に負えず。 どなたか教えてください。

  • PL/SQLにてカーソル名を変数に

    PL/SQLにて、カーソル名を変数にしたいのですが、どうすればよいのでしょうか? 具体的には以下のとおりです。 DECLARE CURSOR Cur1 IS SELECT K1,K2 FROM EMP; BEGIN FOR Cur_Rec1 IN Cur1     Cur_Rec1.K1 DBMS_OUTPUT.PUT_LINE(Cur_Rec1.K1); ★ END LOOP; END; ★の部分の「Cur_Rec1.K1」を「Cur_Rec1.K2」として、置き換えて使用したいのです。(2回書きたくない) 初心者で、申し訳ないです。どうか、ご教授ください。

  • SQLで、重複レコードを削除

    no type name ---------------------------- 1 1 peach 1 1 peach 2 5 tomato 4 6 apple 4 6 apple 1 1 peach  上記のように、重複するレコード(行)が存在してしまっているテーブルで、重複をなくす処理を、SQLで簡単に行なうにはどうしたら良いでしょうか。MySQLです。上の例では、下のように更新したいのです。よろしくお願いします。 no type name ---------------------------- 1 1 peach 2 5 tomato 4 6 apple

    • ベストアンサー
    • MySQL
  • ストアド実行時のエラー「参照しているコレクションは初期化されていません」

    以下のようなパッケージを作っています。 CREATE OR REPLACE PACKAGE "TEST"."TEST_P" as type test_type1 is table of TEST.TEST_TABLE%ROWTYPE; procedure test2 (ret OUT test_type1 ) ; end; ----------------------------------- 本体 ----------------------------------- CREATE OR REPLACE PACKAGE BODY "TEST"."TEST_P" as procedure test2( ret OUT test_type1 ) is cursor basic_cusor is select * from TEST.TEST_TABLE; BEGIN open basic_cusor; loop fetch basic_cusor into ret(0); exit when basic_cusor%notfound; END loop; END TEST3; end; ---------------------------------------- これをSQL Pluseから set serveroutput on; declare  arg1 TEST.TEST_P.test_type1; begin TEST.TEST_P.test2(arg1); dbms_output.put(arg1(0).coulm1); end; のように実行するとエラーが出ます。 初期化処理とはどのように行えばいいのでしょうか? 最終的にはSQLServerのストアドようにテーブル のような構造で値を返えせればいいです。

  • 【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;

  • 重複レコードの取得

    すみません。。重複レコードの取得方法に困っています。 やりたいのは以下です。 テーブルA 項目1| 項目2| 項目3| 11 | 11 | 01 | 12 | 11 | 02 | 13 | 11 | 04 | 14 | 11 | 04 | 上記の項目1は主キーです。 抽出したいのは下記のみです。 項目1| 項目2| 項目3| 13 | 11 | 04 | 14 | 11 | 04 | 色々SQLを組んで試しては見てるのですが。。。。 select * from テーブル where ((項目3) in (SELECT 項目3 FROM テーブル GROUP BY 項目3 having count(*)>1)) 上記SQLだと項目3を主キーごとにカウントしてるみたいなので 意図した結果が抽出されないのです・・・・・。 項目2と項目3を結合して重複のチェックをすればよいのか?? とも思いますがSQL自体が1本で完結したいので よく分からなくなってしまいました。。。。。 皆さんご教示宜しくお願い致します。

  • 期間の重複を調べるSQL文について・・・

    EVENT --+------------+------------+ id | start_date | end_date --+------------+------------+ 0 | 2007-06-01 | 2007-06-03 | --+------------+------------+ 1 | 2007-06-04 | 2007-04-06 | --+------------+------------+ 2 | 2007-06-02 | 2007-06-05 | ↑こんな感じでイベントを管理するテーブルがあります。 イベントの開催期間の重複を出力するSQL文を書きたいのですが、 何かいい案はありませんでしょうか??? 結果的には重複し合っているレコードのidを出力させたいです。 よろしくお願いします。