• 締切済み

カーソルを使って、最終行レコードの判断はどうすればよいのでしょうか。

カーソルを使って、最終行レコードの判断はどうすればよいのでしょうか。 処理はオーソドックスなスタイルでコーディングしているとします。 「ループ処理内で、FETCH NEXTした際に、最終行か判断したい」という質問です。 EOFで最終行だと判断するのは一般的ですが、ループ内で通常行と最終行の切り分けをしたいのです。特に何かの制約や事情があるわけではありませんので、実現できればそれでOKです。 要するに、最終行レコードが、通常行レコードの処理とかぶらなければ、用件は満たせるのですが、あまり懲りたくもないのもあって、ちょっと実装イメージが思い浮かばず、困ってます。 ご回答お願いします。

みんなの回答

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

#1,#2です。 @@CURSOR_ROWSが件数を返すのはSTATIC/KEYSETカーソルのみのはずです。 STATICは指定してますよね?

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

動的カーソルという言葉はどの意味でつかわれているのでしょうか? SQL Serverで動的カーソルと言えば、カーソル処理中もすべての更新が反映するカーソルのことですが。。。 でも、この手の処理にカーソルを使う発想がOracleっぽい気がしますので(SQL Serverでは普通カーソルは使わないケースです)、おそらくは「動的SQLをバインドしたカーソル」の意味でつかわれているのではないかと推測しました。 そうすると、サンプル以下の通りです。 DECLARE @FLD int DECLARE @CNT int DECLARE @sql varchar(MAX) SET @sql = 'DECLARE C CURSOR STATIC FOR SELECT FLD FROM TBL' EXEC (@sql) OPEN C SET @CNT=@@CURSOR_ROWS FETCH NEXT FROM C INTO @FLD WHILE (@@FETCH_STATUS=0) BEGIN SET @CNT=@CNT-1 IF (@CNT=0) PRINT 'LAST ROW:'+CONVERT(varchar,@FLD) ELSE PRINT 'REGULAR ROW:'+CONVERT(varchar,@FLD) FETCH NEXT FROM C INTO @FLD END CLOSE C DEALLOCATE C 読み違えていればごめんなさい。

Hyde_Works
質問者

補足

やりたいことの意図は合ってるのですが、うまくいきませんでした。 SET @CNT=@@CURSOR_ROWSの部分で、カーソルで拾ったレコード数が保持されていることを期待しましたが、マイナス値で、絶対値としてもレコード数とは違うようです。 当方のコーディングがヘマってるかもしれませんが… 他に追われて、なかなか調査しきれてませんが、SET @CNT=@@CURSOR_ROWSという箇所では、レコード数が取得できると思ってよいでしょうか。でないと、デクリメントしても意味ないですしね。動的にバインドしても成り立ちますよね。この部分が少し気になってます。

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

凝ったことは必要ないならば、単純に件数で判断しては? DECLARE @FLD int DECLARE @CNT int DECLARE @C CURSOR SET @C = CURSOR FAST_FORWARD FOR SELECT FLD FROM TBL SET @CNT=@@ROWCOUNT OPEN @C FETCH NEXT FROM @C INTO @FLD WHILE (@@FETCH_STATUS=0) BEGIN  SET @CNT=@CNT-1  IF (@CNT=0) PRINT 'LAST ROW'  ELSE    PRINT 'REGULAR ROW'  FETCH NEXT FROM @C INTO @FLD END

Hyde_Works
質問者

補足

要件が足りてました。ごめんなさい。 (1) カーソルは動的カーソルで行いたい (2) 回答の例で付け加えで言いますと、@FLDを表示したい。 というイメージで、ご回答していただけたらうれしいです。 よろしくお願いします。

関連するQ&A

  • EXCEL-VBAでワークシートのデータがはいっている最終の行番号の取得

    ExcelVBAは不得意のものです。 ワークシートのA列にデータが入っているのですが、10行目までの時もあれば20行目までデータが入っている場合もあります。データが入っている最終行の行番号を取得したいのですがどうしたら良いのでしょう。 何をするかというと、その番号を取得してループ処理をしたいのです。For i=1 To 最終行の行番号みたいに 多分EOFなんて指定じゃないですよね

  • 一行目のレコードを2度表示させたい。

    レコードを読み込むのとは別に、最終書き込み者(ソートした最初のレコード)を表示させたいのですが、mysql_fetch_array($rst)を読み込ませると1位行目が消え、次ぎにmysql_fetch_array($rst)が読み込む時には2行目からになります。 ------------------------- 最終書き込み者 一太郎さん「一番目のタイトル」 -レコードの一覧- □一太郎 一番目タイトル □次郎  2番目のタイトル □佐武郎 三番目のタイトル ------------------------- としたいのですが。 SQLを2度実行すればできるのですが、無駄な処理な気もします。 別のテーブルやこの情報だけtextに保存するのも無駄な気もするし。 //一番目をゲット $sql = "select * from siritori order by db_no desc limit 1;"; $rst = mysql_query($sql,$con); //$rst2 = $rst; $col = mysql_fetch_array($rst); print "最終書き込み者".$col["name"]."さん".$col["title"]."<hr>"; //一覧を表示 $sql = "select * from siritori order by db_no desc limit 10;"; $rst = mysql_query($sql,$con); //SQL配列読み込み(select文) while($col = mysql_fetch_array($rst)){ print $col["name"]."さん".$col["title"]."<br>".$col["kome"]."<hr>";} //$rst2 = $rst; 配列をコピーできないかなー?とかもやったのですができない。 なんとか巧い解決方法はないでしょうか? 連想配置や、MySQLには詳しくないのでお教えください。

    • ベストアンサー
    • MySQL
  • (x 行処理されました)を表示させないのは可能か

    クエリアナライザ、sqlcmdなどでselectを実行した場合、処理結果レコードの最終行の後に(x 行処理されました)が必ず表示されてしまうのですが、表示させない方法をご存じの方、ご教示いただけないでしょうか。 select結果をテキストファイル出力したものをそのままプログラムで使用したいのですが、最終レコードの後に(x 行処理されました)の行など数行が余分にあるため、毎回テキストファイルを開いて手作業で消さなくてはならず、困っております。

  • CSV形式のファイルを読み込んでテーブルに格納するには?

    VB6でCSV形式のファイルを読み込んで それをデータベースに書き込みたいのですがどうやれば いいか分かりません・・・。 1レコードが1行に書かれている固定長のレコードなら 1行ずつ読み込んでそれをループさせてEOFになるまで という風に読みこんでいたのですが、 CSVの場合はどのようにすればよいのでしょうか? 基本的には同じような考えのような気がするのですが。 プログラミング初心者ですみません。 どなたか分かりやすいサンプルなど教えてもらえませんでしょうか?

  • レコードセットのループ処理でエラー・・・

    簡単なことだと思うのですが、解決できなくこまっております。お助けください。 以下のコーディングで、データの取得は出来ているのですが、「Do Until rs1.EOF」でエラーとなります。 SOURCE----------------------------------------- sql = "Select No from t01" Recordset.Open sql, dbc, 3 If rs1.EOF Then Response.Write "データナシ<BR>" ←表示されません。 else Do Until rs1.EOF ←この行でエラーとなります。 Response.Write "No=" & rs1("No").Value rs1.MoveNext Loop end if Error-------------------------------------------- ADODB.Field (0x80020009) BOF と EOF のいずれかが True になっているか、または現在のレコードが削除されています。要求された操作には、現在のレコードが必要です。 因みに、Do Untilを使用せず  Response.Write "No=" & rs1("No").Value  rs1.MoveNext  Response.Write "No=" & rs1("No").Value と記述すると正常にデータが表示されます。 「Do Until rs1.EOF」で発生するエラーの回避方法を御教示願います。

  • カーソルがコミットするとクローズされてしまう。

    オラクルのDBで環境はUNIX(IBMのマシン)です。 DBについて詳しくありませんが、以下のようなことを行いたいと考えています。 1.あるDB(DB-A)のレコードを特定のキーの昇順に全レコード読み込む。(特定のキーは、例えば商品コードなど) 2.1レコードを読み込む毎に、他のDB(DB-B)を読み込んだレコードを元に、更新したい。 その際、1レコードを読み込む都度、 2-1.トランザクションの開始 2-2.DB-Bの更新 2-3.コミット又はロールバック のようにしたい。 上記のことを考えて以下のような作りにしました。 1.カーソルのオープン 2.以下のループを作成  2-1.DB-Aから1レコードのフェッチ  2-2.トランザクションの開始  2-3.DB-Bの更新  2-4.コミット(ロールバック) しかしながら、コミット(又はロールバック)を行うことにより、カーソルがクローズされてしまい、最初の位置にカーソルが戻ってしまいます。(私がコーディングして試験したわけではありません。このような報告をうけました) それで、カーソルが戻らずに、全レコードを処理するようにしたいのですが、どのようにしたら良いのでしょうか。ご存じの方おりましたらアドバイスをお願いします。

  • バッチ処理でレコード数が多いテーブルの結合について。

    バッチ処理でレコード数が多いテーブルの結合について。 300~500万件程度のテーブルが二つあり、これを結合して情報を取得したいと考えています(両者は1:1ではなく、ない場合も正常な構成です)。 またこの二つのテーブルはレコードを履歴として保持しており、ある時点の最新のレコードを取得する必要があります(PKの内、ある1項目がMAXなものを取得する想定)。 件数が件数なのでまともな時間で返ってくるかという懸案があり、どのように実装を進めればパフォーマンス問題のリスクを抑えられるかを考えています。 SQLでjoinせずにテーブルをある時点の最新のレコードを別々に取得して、javaの処理でループして結合するなど・・・。 何かよい方法がありましたらアドバイス頂けないでしょうか。

    • ベストアンサー
    • Java
  • ADOでループすると1レコードずつ飛ばしてしまう

    アクセスなのですが Sub test() Set cn = CurrentProject.Connection rs.Open "テーブル", cn, adOpenKeyset, adLockOptimistic rs.Filter = "(店名 = '" & str店名 & "') And (URL = '未')" For j = 1 To rs.RecordCount rs("URL") = "http" rs.Update rs.MoveNext Next rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing End Sub このようにして、既存のレコードにフィルタをかけて該当のレコードの値を更新しているのですが rs.MoveNext をいれると、 1レコード目、3レコード目、5レコード目・・・と言う順番になってしまい、 最終的にrs.RecordCountの数を越したレコードを指定してしまい 実行時エラー 3021 「BOFとEOFのいずれかTRUEになっていか、または現のレコードが要求された操作には、現在のレコードが必要です。」 となってしまいます。 だからって rs.MoveNextをいれないと、rs.RecordCountに達するまで、 いつまでも同じレコードをループしてしまいます。 1レコードずつ順番にデータを掴む方法を教えてください。

  • 行単位のデータ比較とカウントアップ方法について

    皆様のお知恵を拝借したく投稿しました。 よろしくお願いします。 perlでのデータ処理で2つの入力ファイルがあります list1 list2 ----------------- ------------------ start end start end 1 10 6 8 12 16 7 14 20 30 35 39 34 42 41 47 80 89 110 130 ----------------- ------------------ この2つのファイルを比較して以下の処理を行ないます (1)list1から見たlist2の1行目を比較し、領域の重複が見られたら両方にフラグを立てる →この場合領域6 - 8で重複が見られる (2)両方の終点を比較し、終点値の小さい方をカウントアップ(次の行へ進む) →1行目の場合、list2の終点が小さいのでlist2の行を進める (3)list1の1行目とlist2の2行目を比較する (4)終点を比較して終点の小さい方の行をカウントアップする →以下(1)~(4)の行程を繰り返す。 (5)上例を比較の流れは以下のとおりになります list1 1-10 , list2 6-8 list1 1-10 , list2 7-14 list1 12-16 , list2 7-14 list1 12-16 , list2 35-39 list1 20-30 , list2 35-39 list1 34-42 , list2 35-39 list1 34-42 , list2 41-47 list1 80-89 , list2 41-47 list1 110-130 , list2 41-47(行数が足りなくなったらlist2の最後の行と比較する) 最終的にlist1,list2の重複のあるフラグ数をカウント、出力する と言うアルゴリズムです コーディングの流れとしては (1)双方の二次元配列をループで回す (2)始点に注目して重複がないか比較する (3)終点を比較して該当するリストの行数のカウントアップをする というふうになると思うのですが、 (3)のやり方と、最後の片方のリストの行数が足りなくなったときの 比較とカウントアップのやり方がよく実装できません これをperlでコーディングしたいのですが どのようにしたらよいのでしょうか? ご助言いただけますと幸いです

    • ベストアンサー
    • Perl
  • Rubyでファイルの終わりから?行目を得る方法

    Rubyでファイルの再終行から?行目(コマンドのtail的な)の内容を取得しようとした場合、 どのような方法が一番メモリを消費せず、速度が速いのでしょうか? File.openしてループでgetsをしてまず全行取得、取得した内容から最終の?行を得る、のような方法は考えられるのですが、これだと一度ファイルの全てを処理するために、あまり効率が良い感じがしません。 他に何か良い方法は無いでしょうか。

    • ベストアンサー
    • Ruby