• 締切済み

Classic ASP で切断されたレコードセットを使う

http://www.4guysfromrolla.com/webtech/080101-1.shtml 上記のサイトを参考に切断されたレコードセットを利用しようといたしましたが、 ADODB.Recordset エラー '800a0e78' オブジェクトが閉じている場合は、操作は許可されません。 とエラーが発生してしまいます。 レコードセットを取得してくるFunctionの中の、上記サイトでいうoRS.Closeの部分をコメントアウトするとコードは通ります。 いったい何が問題なのでしょうか?上記記事が古いのでもうこの方法は使えないということなのでしょうか。 ご教示のほどよろしくお願い申し上げます。

みんなの回答

noname#158371
noname#158371
回答No.3

この2ちゃんねるでのやり取りは、「どちらの書き方が良いのか?」という質問であるために、回答者は一般論として、「2の方が関数の切り分けとしては良い気がするのですが、関数毎に接続・切断するのは負荷が高いような…。」と言ったと思います。 もし私が回答者なら、この方と同じように回答していると思います。 あくまでどちらのコードの書き方が良いのか?の一般的な質問しているだけですので。 しかし、今回の質問の趣旨は、「切断レコードセットを使った場合」といことになりますので、そうなると話が違います。 今度は「コードの書き方」の問題ではなく、「切断レコードセット」を使った場合になりますので、一般論だけでは片付けられなくなるといったところでしょうか。 2ちゃんねるで、「DBへアクセスする関数を切り出したいのですが、どちらが正しいのでしょうか?ただし切断レコードセットを使いたいので、レコードセットは閉じたくないです」という質問の仕方であれば、今回、私がアドバイスしたような回答を頂けたのではないかと思います。 ひとまず解決したということなので、良かったです。 切断レコードセットの概念は、あまり世の中に知れ渡っていないところがありますので、これを機に普及したらいいなと思います。 参考になれば幸いです。

noname#158371
noname#158371
回答No.2

>以前某所で「DBの接続・切断は関数の中で行うのか、外で行うのか」 という質問をさせていただいた際に、関数の中で行うという回答をいただいたのですが その某所(フォーラムか掲示板だと思いますが)ですが、差し支えなかったらURLを教えて頂けますか? yyyy5555さんが勘違いして捕らえてしまったのか、回答者が間違った情報を提供している可能性があります。 今後、このOKWave系列を見て、同様の問題で悩む方もいると思いますし、 そういった方のためにも正しい情報をご提供する必要があると思いますので、宜しければ、yyyy5555さんが以前情報を仕入れた某所を教えて下さい。 それから、私が示したサンプルコードは結果的に動いたのか、ダメだったのかも教えて頂けますか? 自分が解決したからそれでいいというものではなく、今後、同様の問題で悩まれる方々のためにも、回答者がアドバイスした結果がどうなったのか?だけでもいいので、ご連絡いただけると幸いです。宜しくお願いします。

yyyy5555
質問者

お礼

失礼いたしました。ご提示いただいたサンプルで解決いたしました。 改めてお礼申し上げます。ありがとうございます。 > その某所(フォーラムか掲示板だと思いますが)ですが、差し支えなかったらURLを教えて頂けますか? > yyyy5555さんが勘違いして捕らえてしまったのか、回答者が間違った情報を提供している可能性があります。 前述の某所というのは2chの<%= ASP総合 %> Part.4というスレッドで、 今は落ちてしまっていると思いますので、そのやりとりを下記に掲載いたします。 971 名前:nobodyさん[sage] 投稿日:2008/06/23(月) 18:20:11 ID:??? 質問させてください。 DBへアクセスする関数を切り出したいのですが、 1.DBへの接続・切断は1回だけ Set ObjConn = Server.CreateObject("ADODB.Connection") ObjConn.open XXX GetData() InsertData() ・・・ ObjConn.Close Set ObjConn = Nothing 2.DBへの接続・切断は関数毎 GetData() InsertData() ・・・ Function GetData()  Set ObjConn = Server.CreateObject("ADODB.Connection")  ObjConn.open XXX  Set ObjRS = Server.CreateObject("ADODB.Recordset")  ObjRS.Open StrSQL, ObjConn,3,3  GetData = ObjRS.GetRows  ObjRS.Close  Set ObjRS = Nothing  ObjConn.Close  Set ObjConn = Nothing End Function どちらが正しいのでしょうか。 2の方が関数の切り分けとしては良い気がするのですが、 関数毎に接続・切断するのは負荷が高いような…。 972 名前:nobodyさん[sage] 投稿日:2008/06/24(火) 02:52:35 ID:??? >>971 処理ごとに関数を分ける → 将来どういう呼ばれ方をするかわからない ってことで関数の中で接続から切断までやったほうが良いと思うよ。 どうせIISがコネクションをプールしてるから、それほど負荷は高くない。

noname#158371
noname#158371
回答No.1

切断レコードセットは、コネクションはとじるけど、レコードセットはそのまま生かすという概念のテクノロジーになりますので、レコードセットoRSに対し、Closeを実行してしまうとレコードセットは消滅します。 このサンプルコードの場合、レコードセットの取得要求した側が、既定の処理を終えた後、レコードセットをCloseしてあげる必要があります。 下記のようにしてみてください。(上記サンプルサイトからのカスタマイズ版です) Function GetRS(strSQL) 'this function returns a disconnected RS 'Set some constants Const adOpenStatic = 3 Const adUseClient = 3 Const adLockBatchOptimistic = 4 'Declare our variables Dim oConn Dim strSQL Dim oRS 'Open a connection Set oConn = Server.CreateObject("ADODB.Connection") oConn.Open mydsn,Sean,Grimaldi 'Create the Recordset object Set oRS = Server.CreateObject("ADODB.Recordset") oRS.CursorLocation = adUseClient 'Populate the Recordset object with a SQL query oRS.Open strSQL, oConn, adOpenStatic, adLockBatchOptimistic 'Disconnect the Recordset Set oRS.ActiveConnection = Nothing 'Return the Recordset Set GetRS = oRS 'Clean up... oConn.Close '''''削除する '''''oRS.Close Set oConn = Nothing '''''削除する '''''Set oRS = Nothing End Function 'call the function strSQL = "SELECT * FROM Authors" set RS = GetRS(strSQL) なんかの処理..... なんかの処理...... なんかの処理..... ' レコードセットが不要になった段階でレコードセットを破棄する RS.Close() Set RS = Nothing 以上、これでやってみてください。宜しくお願いします。

yyyy5555
質問者

お礼

前回に引き続きご回答いただきましてありがとうございます。 以前某所で「DBの接続・切断は関数の中で行うのか、外で行うのか」 という質問をさせていただいた際に、関数の中で行うという回答をいただいたのですが、 それはおそらくコネクションの接続・切断についてだったのに、自分が誤解していたようです。 周りに聞けるような人間がいないので非常に助かります。 ありがとうございました。

関連するQ&A

  • レコードセットをcloseする所でエラーが出ます

    レコードセットをcloseする所で ADODB.Recordset (0x800A0C93) このコンテキストで操作は許可されていません。 というエラーが出ます。 どうしてでしょうか? 特別な操作はしてないと思うのですが。

  • ASP レコードセットしたオブジェクトを戻り値に出来ませんか?

    ASPは本当にドキュメントが少なく困っています。 ---Main.asp---------------------------------- Dim RetRec 'DB接続 Call DBOpen() 'SQL文 strSQL = "SELECT・・・・" 'レコードオープン実行 Set RetRec = RecOpen(strSQL) 'レコードカウント取得 RecCnt = RetRet.RecordCount  ・  ・  ・ --DBCon.asp-------------------------- Public Function RecOpen(SQLPrm) 'オブジェクト宣言 Set G_RecMap = Server.CreateObject("ADODB.Recordset") 'レコードオープン G_RecMap.Open SQLPrm, G_Conn, 3, 3, 1 '復帰値作成 RecOpen = G_RecMap Exit Function End Function ----------------------------------------- エラー内容 オブジェクトでサポートされていないプロパティまたはメソッドです。: 'RecordCount' ・・・当然のことながら、復帰値をオブジェクトとして 拾っていないので、上記エラーが表示された。 ------------------------------------------- 上記のようにレコードセットしたオブジェクトは返せますでしょうか?同じ要領で行うと上手く行かないのですが。。。お手数ですが、よろしくお願いします Sessionの使用は禁止となっています。

  • レコードセットのオープン

    修行中のものです。。。 エラーが発生してしまします。 間違いの点をお教え下さい。 自分的には”レコードセットのオープン”がいまいち分かりません。 【 objCon.Open 】 Dim objCon Dim objRS '##### コネクションオブジェクトの生成 ##### Set objCon = Server.CreateObject("ADODB.Connection") '##### レコードセットオブジェクトの生成 ##### Set objRS = Server.CreateObject("ADODB.Recordset") '##### 接続用パレメータの設定 ##### objCon.Provider = "Microsoft.Jet.OLEDB.4.0" '##### MDBの絶対パス指定 ##### objCon.ConnectionString = (Server.MapPath("/") & "データベース") '##### コネクションのオープン ##### objCon.Open '##### データ参照 ##### objRS = "select [ID],[NAME],[URL],[CM1],[CM2],[CM3] from SITE_DATA" %> レコード件数 <%=objRS.RecordCount%> <hr> <% '##### レコードセットのクローズ ##### objRS.Close Set objRS = Nothing '##### コネクションのクローズ ##### objCon.Close Set objCon = Nothing %> お願いします

  • ADOでレコードを閉じるタイミング。。Access2000/VB6/Win2K

    レコードセットを返すFuncitonプロシージャーを作ってみたのですが。。。 下のGet_Recordsの方のレコードセットをCloseすると上の方のDisp_Dataでオブ ジェクトが閉じているといって怒られます。しかし、閉じないと下の方では開きっ ぱなしになると思うのですが。。。どのように処理すればいいのでしょうか? Public P_CN As ADODB.Connection Private Sub Disp_Date()   Dim RS As ADODB.Recordset   Dim SQL AS String    Set RS = Get_Records(SQL)     With RS      If .RecordCount > 0 Then       .MoveLast: .MoveFirst       .Debug.Print !顧客_ID        End If      End With      RS.Close     Set RS = Nothing End Sub Public Function Get_Records(pSQL As String) As ADODB.Recordset   Dim RS As ADODB.Recordset     Set RS = New ADODB.Recordset      RS.Open pSQL, P_CN, adOpenKeyset, adLockOptimistic     Set Get_Records = RS '''    RS.Close '''   Set RS = Nothing End Function

  • レコードセットオブジェクトの閉じ方について

    こんにちは。 ASPでのレコードセットオブジェクトの閉じ方について質問です。 レコードセットオブジェクト(以下:rs)を閉じる際に (1)カッコをつけない場合 → rs.close (2)カッコをつけた場合  → rs.close() とで、何か違うのでしょうか? 「On Error Resume Next」をつけていないプログラムでも、どちらも正常に動作します。 普段はカッコを付けずにコーディングしているのですが、たまたまカッコが付いているプログラムを発見したので質問いたしました。 よろしくお願いいたします。

  • VBAでレコードセットの総レコード数を取得する方法

    Dim con As ADODB.Connection Dim rsData As ADODB.Recordset Dim DNSname$,USERname$,PASSw$,cnt&  Set con = CreateObject("ADODB.Connection")  con.Open "DSN=" & DNSname & "; UID= " USERname & "; PWD=" & PASSw  Set rsData = New ADODB.Recordset  rsData.Open SQL, con  Do While Not rsData.EOF   rsData.MoveLast   cnt=rsData.RecordCount   rsData.First  LOOP といいコードで総レコード数が取得できるかなとやってみたところ、rsData.MoveLastのところで、「行セットは逆フェッチをサポートしていません」というエラーが出ました。 なにかほかの方法で総レコード数を取得する方法があるのでしょうか? 自分で他に試したことは、rsData.EOFまでrsData.MoveNextでもっていきrsData.EOF-1レコードの.RecordCountを取得すしようと試みましたが、最後のレコードまできても.RecordCountは「-1」のまま変化しませんでした。レコードセットの呼び込み方が不味いのでしょうか?

  • ASPからSELECT文を複数発行するには?

    こんにちは。 ASPからSELECT文を複数発行する際に 「ADODB.Recordset エラー '800a0e78' オブジェクトが閉じている場合は、操作は許可されません。 」 とエラーメッセージが表示されます。 同じ記述方法で、1つのSELECT文を発行するのは大丈夫です。 レコードセットをオープンした後でエラーになってるようです。 最初のSELECTで #tempを作成して 次のSELECTで参照しています。 このような処理の場合、どうすれば良いのでしょうか??

  • ASP レコードセットオブジェクト

    コレクションにFieldsからAddし、展開するとエラーが発生します。(エラーは下記) レコードが単純に取得できていないと見せかけて、Recordcountはしっかりと取れてますし、仮にコレクションAdd前に変数に置き換えると問題なくAddされています。 この現象について何か問題は考えられますか? 補足につきましては徹夜作業につき随時行います。 ソースが長すぎて、個別で送ります。 例)  (1)'オブジェクト直接からのAddの場合 MSTCol.Add "ID", PrmRec.Fields("ID")・・・×  (2)'変数に置き換えてからのAddの場合 S_ID = PrmRec.Fields("ID") MSTCol.Add "ID", S_ID ・・・○ --ソース---------------------------------------- 2|SQL = "SELECT ID, NAME, TEL FROM MST_PEOPLE ORDER BY ID" 3| 'DB接続&レコードセット 4| Set RetRec = DBCon_RecSet(SQL) 5| 'レコード置き換え処理実行 6| Set RetListObj = CreateListObj(G_RecSearch) 7|'確認としての処理(テスト段階) 8|Set Item_NO = RetListObj(1) 9|value1 = Item_NO.Item("TEL") 10|Response.Write(Value1) エラー タイプ ADODB.Field (0x800A0BCD) BOF と EOF のいずれかが True になっているか、または現在のレコードが削除されています。要求された操作には、現在のレコードが必要です。 エラー行数13行目

  • Access ADOについて質問です。

    Access ADOについて質問です。 以下コードでレコードセットを返す関数を使用しています。 動作的には問題ないのですが、標準モジュール内のレコードセットをClose及びNothingしていないのが気になります。 Private Sub Form_Open(Cancel As Integer) Dim rs2 As ADODB.Recordset Set rs2 = New ADODB.Recordset Set rs2 = CreateRecordSet("SELECT * FROM T_Standard;") Set Me.Recordset = rs2 rs2.Close: Set rs2 = Nothing end sub '標準モジュール Public Function CreateRecordSet(strSQL As String) As ADODB.Recordset Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Set cn = New ADODB.Connection cn.ConnectionString = "provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=O:\標準DB\StandardBackEnd.mdb" cn.Open Set rs = New ADODB.Recordset rs.Open strSQL, cn, adOpenStatic, adLockReadOnly Set CreateRecordSet = rs ' rs.Close: Set rs = Nothing   ←この部分 ' cn.Close: Set cn = Nothing   ←この部分 End Function 標準モジュール内ではCloseやNothingしなくてもメモリの開放は行われているのでしょうか? アドバイスよろしくお願いいたします。

  • サブフォームのレコード削除

    サブフォーム(帳票)のレコード削除をしたいのですが、レコードセクレタをクリックして選んだレコードではなく、テーブルの最初のレコードから順番に削除されてしまいます。 Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim ret As Integer '接続 Set cn = CurrentProject.Connection 'レコードセットを取得 Set rs = New ADODB.Recordset rs.Open "T支店", cn, adOpenKeyset, adLockOptimistic '削除 ret = MsgBox("表示中のレコードを削除しますか?", vbYesNo + vbQuestion, "削除") Select Case ret Case vbYes rs.Delete Me!sub支店.Form.Requery Case vbNo Exit Sub End Select '終了 rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing WINDOWS98、ACCESS2000をしようしています。よろしくお願いします。