- PR -

Recordsetのレコード数

投稿者投稿内容
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2007-10-09 10:43
お世話になります。

VB(Visual Basic 6.0)より、SQL Server 2000に作成したストアドプロシージャを実行し、
抽出された結果をレコードセットとして取得しています。(記述内容は下記を参照)
その際、RecordCountが「-1」と表示されてしまい、正しいレコード数を取得できません。
(レコードセットの中身は正常に取得できております。)

幾つかホームページ(http://www.red.oit-net.jp/tatsuya/vb/ADO.htm#RecordCount)で
調べてみたのですが、やはりうまくレコード数を取得できません。

以下に、VB内で記述している接続設定部分とSQLに記述しているストアドプロシジャのロジック
を記述しておりますので、どなたかご回答をお願いします。


■VB内の接続設定

Public cmd As New ADODB.Command
Public Conn1 As ADODB.Connection
Public RS As ADODB.Recordset

' ***接続設定
Set Conn1 = New ADODB.Connection
Set RS = New ADODB.Recordset
Conn1.Open "Driver={SQL Server};" & _
"SERVER='サーバー名';" & _
"DATABASE='データベース名';" & _
"User Id='ユーザーID';" & _
"Password='ユーザーパスワード'"

cmd.CommandText = 'ストアドプロシージャ名'
cmd.ActiveConnection = Conn1
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Refresh
RS.CursorType = adOpenStatic
RS.LockType = adLockReadOnly

Set RS = cmd.Execute
msgbox RS.RecordCount' ・・・・・-1になってしまう。


■ストアドプロシージャ

SELECT 項目A, 項目B
FROM データベース名.dbo.テーブル名
GROUP BY 項目A, 項目B
ORDER BY 項目
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-10-09 11:30
こんにちは。

ここ↓おかしいですよ
コード:
Set RS = New ADODB.Recordset 
(省略)
Set RS = cmd.Execute 



こんな感じでどうですか?
コード:
    Dim Conn1 As ADODB.Connection
    Dim RS As ADODB.Recordset
    
    ' ***接続設定
    Set Conn1 = New ADODB.Connection
    Set RS = New ADODB.Recordset
    Conn1.Open "Driver={SQL Server};" & _
        "SERVER='サーバー名';" & _
        "DATABASE='データベース名';" & _
        "User Id='ユーザーID';" & _
        "Password='ユーザーパスワード'"
    
    RS.Open "exec 'ストアドプロシージャ名' ", Conn1, adOpenStatic
    
    MsgBox RS.RecordCount


ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2007-10-09 12:33
Tdnr_Symさん、お返事ありがとうございます。
ご指示頂いたように修正したところ、正常にRecordCountを取得できました!

確かによく考えてみると「RecordSet Open」という記述が無いことに気付きました。丁寧なご指摘ありがとうございました。今後ともよろしくお願いします!

失礼します。
ともこ
大ベテラン
会議室デビュー日: 2007/09/14
投稿数: 111
投稿日時: 2007-10-09 13:40
Tdnr_Symさん、別の問題が発生しました。

今までは、
cmd.CommandText = 'ストアドプロシージャ名'
cmd.Parameters(1).value = 'パラメータ'
Set RS = cmd.Execute
にてパラメータを指定した形でストアドプロシージャを実行していました。
今回、
「RS.Open "ストアドプロシージャ名'", Conn1」という形に変更した場合、
どのようにパラメータを指定したら良いのでしょうか?

もしよろしければもう一度ご指示を頂けないでしょうか?
よろしくお願いします。
tkrn
ベテラン
会議室デビュー日: 2005/10/25
投稿数: 61
投稿日時: 2007-10-09 14:11
試してませんので、できなかったらすみません。
元のソースコードで
RS.MoveLast
RS.MoveFirst
を実行した後に、RecordCountを取得できませんか?
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-10-09 14:16
引用:

確かによく考えてみると「RecordSet Open」という記述が無いことに気付きました。


いろいろな方法があるから、別に Recordset の Open がなくてもいい場合もあります。あなたが最初に書いていた Command の Execute を使う方法も間違っていません。パラメータを与えたいなら、当初のとおり Command を使うほうが良いでしょう。

Set RS = cmd.Execute で、オブジェクト変数 RS にあらたなインスタンスが設定されるので、それまでの RS に対する設定は何の意味も持ちません。つまり、adOopenStatic や adLockReadOnly は機能していません。

もっとも簡単な解決方法はクライアントカーソルを使うこと。とりあえず、Conn1.Open ... の前に Conn1.CursorLocation = adUseClient を入れてみてください。それで大丈夫なはず。

それから全体的にコードが気になりますね。接続文字列の Driver={SQL Server} は、アドホック ODBC を使用する記述ですね。私なら Provider=SQLOLEDB と書いて OLE DB Provider を使うようにします。
tkrn
ベテラン
会議室デビュー日: 2005/10/25
投稿数: 61
投稿日時: 2007-10-09 14:29
今リファレンスを見たら
引用:

返された Recordset オブジェクトは常に読み取り専用で、前方スクロール タイプの カーソルです。Recordset オブジェクトに、より多くの機能が必要な場合は、まず、目的のプロパティ設定を持つ Recordset オブジェクトを作成し、次に、Recordset オブジェクトの Open メソッドを使ってクエリを実行して目的のカーソル タイプを返します。


とありましたので、
Execute後、
RS.Open ,,adOpenStatic, adLockReadOnly
を実行すれば元のソースでも取れそうですね。

[ メッセージ編集済み 編集者: tkrn 編集日時 2007-10-09 14:35 ]
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-10-09 14:32
こんいちは。

引用:

ともこさんの書き込み (2007-10-09 13:40) より:
どのようにパラメータを指定したら良いのでしょうか?



パラメータが必要でしたか。
では、こんな感じでどうでしょう?

コード:
Public cmd As New ADODB.Command 
Public Conn1 As ADODB.Connection 
Public RS As ADODB.Recordset 

' ***接続設定 
Set Conn1 = New ADODB.Connection 
Set RS = New ADODB.Recordset 

Conn1.Open "Driver={SQL Server};" & _ 
"SERVER='サーバー名';" & _ 
"DATABASE='データベース名';" & _ 
"User Id='ユーザーID';" & _ 
"Password='ユーザーパスワード'" 

cmd.CommandText = 'ストアドプロシージャ名' 
cmd.ActiveConnection = Conn1 
cmd.CommandType = adCmdStoredProc 
cmd.Parameters(1).value = 'パラメータ'

RS.Open cmd, , adOpenStatic

msgbox RS.RecordCount


スキルアップ/キャリアアップ(JOB@IT)