• ベストアンサー

複数SQL発行について

お世話になります。 VB.NET2003とSQLServer2005にて開発を行っております。 Aテーブルからデータを取得してその取得データを元にBテーブルを参照する。 と、言うのがあるのですが、 Bテーブル参照時に「この接続に関連付けられている DataReader が既に開いています。この DataReader を最初に閉じる必要があります。」の エラーとなってしまいます。 複数SQLを発行する場合、再度接続を行わなければならないのでしょうか? 同一接続内で複数のSQLを発行することは出来ないのでしょうか? どなたかご存知でしたらお教え願います。 以下、ソース ' 変数宣言 Dim objDBConnect As SqlConnection Dim objDBTran As SqlTransaction Dim objSqlCmd As SqlCommand Dim objSqlDRA As SqlDataReader Dim objSqlDRB As SqlDataReader ' データベース接続 objDBConnect = New SqlConnection("接続文字列") objDBConnect.Open() ' トランザクション開始 objDBTran = objDBConnect.BeginTransaction(IsolationLevel.ReadCommitted) ' SQL発行 objSqlCmd = New SqlCommand("SELECT * FROM A_TABLE", objDBConnect) objSqlDRA = objSqlCmd.ExecuteReader() While objSqlDRA.Read() objSqlCmd = New SqlCommand("SELECT * FROM B_TABLE", objDBConnect) objSqlDRB = objSqlCmd.ExecuteReader() ←ここで、エラーとなってしまいます。 End While

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

  • ベストアンサー
  • mahny
  • ベストアンサー率74% (57/77)
回答No.2

#1です。 ごめんなさい。1接続に対して1つだけみたいです。 ▼MSDN引用 DataReader の終了 DataReader を使い終えたら、Close メソッドを呼び出す必要があります。 Command に出力パラメータや戻り値が含まれていても、DataReader が終了するまでは使用できません。 DataReader が開いている間、Connection はその DataReader によって排他的に使用されています。元の DataReader が終了するまでは、その Connection に対してはどのコマンドも実行できません。別の DataReader を作成することもできません。

参考URL:
http://msdn2.microsoft.com/ja-jp/library/haa3afyz.aspx
yu1ohni
質問者

お礼

mahny様回答ありがとうございます。 >1接続に対して1つだけみたいです。 という事は、DataReader では出来ないという事ですね。 DataReaderを使用するなら、DataReaderから別な入れ物にコピーして再度、DataReaderにて取得を行う。 の方法でいくしかないでしょうか? また、別な方法がありましたら教えて頂けませんでしょうか?

その他の回答 (4)

回答No.5

説明を読む限りselect文ないで結合させて一つのSQL文にすれば良いだけの 様に思えるのですが

  • qtea
  • ベストアンサー率77% (38/49)
回答No.4

DataReaderは1つの接続に対して、1つしかopenできません。 なので、接続(SqlConnection)を2つ作るか、別な入れ物にコピーして…かのどちらかではないでしょうか。 別な入れ物にコピーする場合は、データセットを使うのがおすすめです。

  • PED02744
  • ベストアンサー率40% (157/390)
回答No.3

素直に、DataAdapter/DataSetは使えないのでしょうか? 手元に例がないので、うろ覚えで書きますが、 Dim conn as Connection Dim sql as String Dim dad1 as DataAdapter Dim dad2 as DataAdapter Dim dSet as DataSet conn = new Connection("Data Source=~~~") sql = "SELECT ~ FROM TBL_A WHERE ~~~" DataAdapter dad1 = new DataAdapter(sql, conn) dad1.Fill(dSet, "TBL_A") sql = "SELECT ~ FROM TBL_B WHERE ~~~" DataAdapter dad2 = new DataAdapter(sql, conn) dad2.Fill(dSet, "TBL_B") こんな感じ

  • mahny
  • ベストアンサー率74% (57/77)
回答No.1

そんなことは無いと思います。 While objSqlDRA.Read() objSqlCmd = New SqlCommand("SELECT * FROM B_TABLE",objDBConnect) objSqlDRB = objSqlCmd.ExecuteReader() '←ここで、エラーとなってしまいます。 End While 手元にVB環境無いので勘で書きますが、 上記ループの2週目でエラーが発生していませんか? だとすれば、1週目のループで objSqlDRB As DataReader が出来上がっているのに そこにさらにDataReaderオブジェクトを重ねようとしたからじゃないですかね。。。

関連するQ&A

  • VB.NETでSqlClientを利用して複数テーベルを見る方法

    今VB.NETで SQLデータベースからデータを取得して動作するプログラムを作っているのですが、テーブルを複数参照する方法がわかりません。教えてください~ ■今のプログラム(おおざっぱに) Public DBcn As SqlClient.SqlConnection = Nothing Public SQLcmd As SqlClient.SqlCommand Dim dr As SqlDataReader DBcn = New SqlClient.SqlConnection SQLcmd = New SqlClient.SqlCommand DBcn.ConnectionString = "接続情報省略" DBcn.Open() SQLcmd.Connection = DBcn SQLcmd.CommandText = "select * from AAA " dr = SQLcmd.ExecuteReader() While dr.Read() = True   ※処理A End While このプログラムの処理Aの中に もう一度Select文で他のテーブル(データベース同じ)を参照したいのですが、どのようにすればよいのでしょうか? いろいろ試してみたのですがどれもできず;;困っております。

  • C#でのSQLへのアクセスについて

    SQL Serverのテーブルをコンソール上に表示する為のコードを書いたのですが SqlConnection SqlCommand SqlDataReader に対してエラーが出しまい、修正方法が分からず、どなたか教えて頂けないでしょうか? 【ソースコード】 using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using Microsoft.Data.SqlClient; static void Main(string[] args) { string connectionString = "Data Source=○○;Initial Catalog=○○;User ID=○○;Password=○○;"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand("SELECT * FROM [○○]", connection)) using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader["column1"]); Console.WriteLine(reader["column2"]); } } } }

  • SQLServer2008のDate型について

    SQLServer2008のDate型についてお聞きします Date型には日付のみセットされると思うのですが VB2010から接続表示すると時刻データまで表示されてしまいます テーブルデータの表示では「20120305」 VBでは「20120305 0:00:00」 となっております。 期待する動作はVBで「20120305」と表示されることです 接続はこの様にしております。 Dim cn As New SqlConnection(ConnectionString~) Dim cmd As New SqlCommand("SELECT * FROM Test1", cn) cn.Open() Dim dr As SqlDataReader = cmd.ExecuteReader While dr.Read() Trace.WriteLine(dr("Date").ToString) End While なぜ時刻までセットされてしまうのか理解できません。 ご指導よろしくお願い致します。

  • SQLとC#connectについて

    独学で勉強しているのですがさっぱり分かりません...。 C# visual studio へ SQL server情報を読み込みたいのですが...Button1を押したら、sql に作成してある(ingredientという) データをrichtextbox へ送りたいです。 今のところ、SQLにcommandを送り、開き、リーダーで呼びました。 SqlConnection sc = new SqlConnection(@"........."); SqlCommand cmd; cmd = new SqlCommand ("Select * from ingredients", sc); sc.Open(); SqlDataReader reader = cmd.ExecuteReader(); その後作っておいたクラスでリストを作りストアしました。ingredientにはidとnameだけです。 List<Ingredient> ingredients = new List<Ingredient>(); while (reader.Read()) {  string testID = reader["id"].ToString(); string ingName = reader["name"].ToString(); Ingredient oneIng = new Ingredient(Convert.ToInt32(testID), ingName); ingredients.Add(oneIng);} 今リストの中に情報が入っているということは分ります。でも、これをrichtextboxにどう整理して入れるのかは分りません。教えて下さい!!!

  • コンボボックスのSelectedItemの使い方

    エリアテーブルを取得し コンボボックスの見える値は「値」にして コンボボックスを取得するときには「コード」を 取れるようにしたいと思っています。 どのように書くと取得できるのでしょうか? バインドするやり方が分からなくて 下記のようになっています。 Dim strSql As String Dim dr As SqlClient.SqlDataReader = Nothing Dim daAdp As New SqlClient.SqlDataAdapter Dim cmd As New SqlClient.SqlCommand Dim ds As DataSet = New DataSet() mConn = New SqlConnection 'DBのオープン  Conn.DbConnect()   Dim dbCmd As SqlCommand = Nothing 'SQL発行 strSQL = "SELECT コード,値 " strSQL = strSQL & "FROM エリア" Conn.ExecSqlSelect(strSql, dr)   ComboBox1.Items.Clear() Do While dr.Read ComboBox1.Items.Add(dr.GetString(1)) ComboBox1.SelectedItem = dr.GetString(0) Loop

  • エラーを発生させたい(SQLサーバーへの接続)

    ネットのサンプルコードでSQLサーバーの接続テストをしましたが、 存在しないSQL文でもエラーになりません。(vb2005です) Sub sqlサーバーへ接続() ' 接続文字列を生成する Dim Cn As New System.Data.SqlClient.SqlConnection Dim SQL As System.Data.SqlClient.SqlCommand Dim stConnectionString As String = String.Empty stConnectionString &= "Data Source = ××××\SQLEXPRESS;" stConnectionString &= "Initial Catalog = ×××;" stConnectionString &= "Integrated Security = SSPI;" ' SqlConnection の新しいインスタンスを生成する (接続文字列を指定) Dim cSqlConnection As New System.Data.SqlClient.SqlConnection(stConnectionString) ' データベース接続を開く cSqlConnection.Open() SQL = Cn.CreateCommand SQL.CommandText = "SELECT テーブル1.あああフィールド1 FROM テーブル1" '間違ってても進んでしまう。 ' 接続に成功した旨を表示する MessageBox.Show("Microsoft SQL Server に接続されました") ' データベース接続を閉じる (正しくは オブジェクトの破棄を保証する を参照) cSqlConnection.Close() cSqlConnection.Dispose() End Sub 「あああフィールド1」なんて存在しないのに、先に進んでしまいます。 エラー処理の仕方を教えてください。 よろしくお願いします。

  • VB2005で、Delete文(SQL Server2005 Express)

    VB2005で、Delete文を使ったプログラムを書きたいのですが。 SQL Server2005 ExpressEditonを使っています。 テーブル(WK_BoxList)から 列名(ComputerName)=XXXに該当するレコードを削除する。 そこで下記のコードを書いたのですが、 1,2のSQL文だと問題ようなのですが。 3の時に、列名'SYSTEM'が無効です。とメッセージがでてしまいます。 テーブル(WK_BoxList)には列名'SYSTEM'というのはありません。 3のようにSQL文は、文字連結させて使えたはずだと思ったのですが。 ちなみにプログラム初心者です。アドバイスをいただきたいのですが、 よろしくお願い致します。<(_ _)> Dim scn As SqlClient.SqlConnection = New SqlClient.SqlConnection(接続文字列) Dim scm As SqlClient.SqlCommand Dim sql As String Dim PcName As String = My.Computer.Name Try scn.Open() ' OK 'sql = "delete from WK_BoxList ' OK '------------1 ' OK 'sql = "delete from WK_BoxList Where ComputerName=1 '-------------- 2 ' NG sql = "delete from WK_BoxList Where ComputerName=" & PcName '----------3 scm = New SqlClient.SqlCommand(sql, scn) scm.ExecuteNonQuery() Catch ex As Exception MessageBox.Show(ex.Message) End Try scn.Close() 環境 WindowsXP Pro SP2 VS2005Pro Sp1 SQL Server2005 ExpressEditon

  • VB.Net データ読み取りの For Each

    お世話になります。 .Net 駆け出しの者です。 下記のような場合(全く違う記述でもいいです)、SQLDr("項目名")で値を取得できると思うのですが、直に項目名を書かず変数で値を取得したいのと、While と For Each 文なんかを組み合わせて全レコード、全フィールドの値を取得したいのです。 下記で言いますと例えば2レコード 3項目 合計で6つの値があるとすると データ座標 1,1 が A 1,2 が B 1.3 が C 2,1 が D 2,2 が E 2,3 が F 結果的に A,B,C D,E,F このような形でデータを取得したいのです 何卒よろしくお願いいたします。 Dim SQLCon As SqlConnection = New SqlConnection(接続文字列) Dim SQLCmd As SqlCommand = New SqlCommand(SQL文, SQLCon) SQLCon.Open() Dim SQLDr As SqlDataReader = SQLCmd.ExecuteReader Dim value As Boolean value = SQLDr.HasRows 'True と仮定します     ’***********************************************************     ここからが質問です。 SQLDr("項目名")と記述すれば値を取得することは     わかるのですが、     直に項目名を書かず編集ですべての値を取得する記述の仕方をお教えくださいませ。     たとえば     Dim Cnt as Integer = 0     Dim CntField as Integer = 0     While SQLDr.Read()         For Each o As Read In SQLDr.Read             こんな感じで全データを抽出したいのです             こんな記述はないと思いますが             SQLDr(CntField) 変数で値を取得したいのです             2つの変数の値が座標データ             SQLDr(CntField)が値データになります。             CntField = CntField + 1 'フィールドの位置         Next       Cnt = Cnt + 1 'レコードの位置       CntField = 1     End While     ’*********************************************************** SQLDr.Close() SQLCon.Close()

  • エクセルからSQLの接続の仕方

    エクセルを使ってMSSQLに接続したいのですが、エラーがでて接続できません。 なぜでしょうか? [エラー内容] コンパイルエラー: ユーザー定義型は定義されれいません。 コードの下の部分で発生します。 Dim Cn As New System.Data.SqlClient.SqlConnection [コード] Private Sub CommandButton1_Click() Dim St As String Dim Cn As New System.Data.SqlClient.SqlConnection Dim SQL As System.Data.SqlClient.SqlCommand Dim ServerName As String Dim UserID As String Dim Password As String Dim DatabaseName As String ServerName = "TEST-PC" 'サーバー名(またはIPアドレス) UserID = "sa" 'ユーザーID Password = "password" 'パスワード DatabaseName = "TEST_DB_20140801" 'データベース St = "Server=" & ServerName & ";" & "User ID=" & UserID & ";" & "Password=" & Password & ";" & "Initial Catalog=" & DatabaseName Cn.ConnectionString = St SQL = Cn.CreateCommand SQL.CommandText = "SELECT * FROM LOG_DATA_XLINE" Cn.Open MsgBox (SQL.ExecuteScalar) Cn.Close SQL.Dispose Cn.Dispose End Sub

  • ASP.NET

    VBで作成しています。 下記はSQLサーバーのデータベースを使ったプログラムですが、Microsoft Office Accessのデータベースを使う場合は、どのように変更すればいいでしょうか?教えて下さい。 お願いします。 <プログラム> Dim strSQL As String Dim sqlDa As SqlClient.SqlDataReader Dim dr As DataRow 'SQL文 strSQL = "SELECT * FROM Data1 Dim cmdSQL As New SqlClient.SqlCommand With cmdSQL .Connection = Action .CommandType = CommandType.Text .CommandText = strSQL End With Try Action.Open() sqlDa = cmdSQL.ExecuteReader (以下省略)