VB.Netデータ読み取りで変数を使用して全データを取得する方法

このQ&Aのポイント
  • VB.Netでデータを読み取る際、変数を使用して全データを取得する方法を知りたいです。
  • 具体的には、SQLDrオブジェクトを使用して項目名を直接指定せずに全フィールドの値を取得したいです。
  • WhileループとForEachループを組み合わせて、データの座標と値を取得し、一括して取得したいです。
回答を見る
  • ベストアンサー

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()

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

  • ベストアンサー
  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.1

SqlDataReader.itemプロパティは、引数としてString(列名)の他にInteger(列番号)を取ることができる。なのでご要望としては以下の通りになるのかな。一番内側のループでCntFieldの0~SQLDr.FieldCount-1が列番号になるので、これをインデックスとして配列にぶっこむがいい。 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 と仮定します     Dim Cnt as Integer = 0     While SQLDr.Read()         For CntField As Integer = 0 To SQLDr.FieldCount - 1 Step 1             Dim o As Object = SQLDr(CntField) ' ここを適当に直して!         Next       Cnt = Cnt + 1 'レコードの位置     End While     ’*********************************************************** SQLDr.Close() SQLCon.Close()

kyokotan12
質問者

お礼

anmochi さん お世話になります。 ご提示いただいた記述にて無事に座標データとともに値データも取り出すことができました。MARU4812 さんのご指摘があった出力順番は保障されないことも念頭におき作業を進めようと思います。 100以上のフィールドの出力のコーディングを考えた場合、萎えそうな気持ちになり、こちらで質問させていただいた次第でございます。 大変勉強になりました。ありがとうございました。

その他の回答 (2)

  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.3

> 出力順番は保障されないことも念頭におき作業を進めようと思います。 ん? いやそんな事はないよ。 select A, B, C from TABLE1 order by A の結果を受け取る場合、 SqlDataReader.item(0)は絶対にA列を指す事がADO.NETによって保証されている。 まぁ、SQLを select D, A, B, C from TABLE1 order by A に直したのにその後ろのプログラムを直してなくって痛い目を見る、またはSQLを select * FROM TABLE1 order by A とかにしといてTABLE1の構造を変えたのにプログラムを直してなくってシステム全体が大変な事になる、というのはあるけど。 しかしこれらはプログラマーの凡ミスまたはシステム改修計画の不備であり、SqlDataReader.item(0)がランダムに違う列を指す(出力順番が保証されない)からではないよね。 もちろん、SQLの方で出力列(select句)をきっちり記述するとか、列のインデックスアクセス+何かに起因する無用なバグを発生させないようなしっかりとしたプログラムを書く必要はあると思うけど。

kyokotan12
質問者

お礼

anmochi さん お世話になります。 100以上のフィールドのことを考えると、select * FROM TABLE1 の形になろうかと思います。なるべく無用なバグを発生させないよう、最悪の時はすべての列をSelect句に記述する方向で進めようと思っております。 重ね重ねありがとうございました。

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.2

質問の回答は#1さんの回答通りです。 でも一般的に、データベースにおいて各フィールドも各データも等価で 明示しない限り順番は保障されていないから、この手のプログラムで 痛い目見たことのある技術者はインデックスで取り出す事は稀だけどね。 SQL文で明示できているなら問題ないけどね。その場合はフィールド名を 指定できたり、フィールド名にルールを作ってプログラムでフィールド名を 生成する場合が多いです。インデックスを指定していると、プログラムの 修正に非常に弱いです。フィールドが後から追加されるとエラーが出ずに データが全部ずれちゃったりするからね。

kyokotan12
質問者

お礼

MARU4812 さん お世話になります。 なるほどインデックスで取り出す際は出力される順番は保障されないのですね、肝に命じておきます。 今回の主旨は、Excelシートに出力するのに座標としてのデータがほしかったのです。フィールドが100近くあり、すべてのフィールドの記述をするととんでもない作業と手作業によるミスがあるかと思い、今回質問させていただきました。 出力される順番が保障されないということは、ご指摘どおりフィールド名を記述してコーディングする必要もあると念頭におき作業にあたろうと思います。 ありがとうございました。

関連する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文で他のテーブル(データベース同じ)を参照したいのですが、どのようにすればよいのでしょうか? いろいろ試してみたのですがどれもできず;;困っております。

  • 複数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

  • VB.NETからのMDBへのデータ接続について教えてください。

    またまたお世話になります。 いろいろ教えていただきながらほとんど出来上がって今最後のログオン部分を作成中です。 VB.NET2003、アクセス2000使用です。 参考にしている本がAccess使いではなくMSDEを使用しているため、データ接続の部分が毎回違っています。 各フォームなどでは余り気にせずに進めたのですが、このログオン処理のところだけ引っかかって進むことが出来ません。 データリンクプロパティでAccessの場合はMicrosoft Jet4.0 OLE DB Providerを指定しなければならないようですが、この場合、Oledbconnectionが作成されます。 MSDEの場合、Sqlconnectionが作成されSQLは以下のように書かれます。 Dim cmd As Sqlclient.Sqlcommand = Sqlconnection1.CreateCommnad() Dim dr As SqlClient.SqlDataReader 'コマンドのコネクション設定 cmd.Connection = SqlConnection1 'コネクションを開く SqlConnection1.Open() OledbConnectionを使って書くにはどういう修正をしたらいいのか、ご教示いただきたくお願いします。

  • DataTableの件数を取得したい

    DataTableの件数を取得したいのですがどのようにすれば取得できますか? Private Function getDataListCnt() As Long Dim DBConnection As New SqlConnection(ConfigurationManager.ConnectionStrings("xxx").ConnectionString) Dim sqlCmd As New SqlCommand sqlCmd.Connection = DBConnection Dim lngRet AS Long Dim dt As DataTable = New DataTable() dt = GetList() ☆ここで取得したい☆ lngRet=??? Return lngRet End Function Private Function GetList() Dim CmdTxt As StringBuilder = New StringBuilder() CmdTxt.AppendLine(" SELECT * FROM TBL WHERE CD='001'") Dim dt = GetDBListData(CmdTxt.ToString()) Return dt End Function

  • コンボボックスの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

  • 現在、ASP.NET(言語:VB.NET)にて、

    現在、ASP.NET(言語:VB.NET)にて、 データ参照、更新系のWebアプリケーションを自学しているものですが、 DAC(Data Access Componet)を利用してSQL Serverのデータを取得、更新する際、 コネクションの閉じ方が分からず困っています。 DACを使用しない場合は、 下記のようにSQLConnectionをUsing句で明示的に括り、 Closeさせることができますが、 DACを使用した場合はTableAdapterからSQLConnectionを取得できず、 同様の実装方法を採れません。 ------------------ Dim mySelectQuery As String = "SELECT * FROM Categories ORDER BY CategoryID" Dim myConnectString As String = "Persist Security Info=False;Integrated Security=SSPI;database=northwind;server=mySQLServer" Dim myCommand As New SqlCommand(mySelectQuery) Using conn AS SqlConnection = New SqlConnection(myConnectString) myCommand.Connection =conn myCommand.CommandTimeout = 15 myCommand.CommandType = CommandType.Text myCommand.ExecuteNonQuery() End Using ------------------ 一方、DACを使用した場合は下記のように実装しております。 ------------------ Dim ta As New SystemError_OriginalTableAdapters.OriginalTableAdapter Dim dt As New SystemError_OriginalDataTable ta.FillBy(dt, id) ' テーブルアダプターのFillメソッドを呼び出すのみで、Closeしているかどうかがわからない。 ------------------ DACでは、Fillメソッド実行後に必ずSQLConnectionがCloseされることが 保証されているなら問題は無いのですが、 そうでない場合、テーブルアダプターからSQLConnectionを取得して、 明示的にCloseさせてやりたいと思っています。 DACを使用した場合のSQLConnectionの取得方法、 もしくはSQLConnectionのCloseの方法についてご教授願えないでしょうか? 以上、宜しくお願いします。

  • VB.Net SqlCommand 共通に

    お世話になります。 VB.Net 駆け出しの者です。 SqlCommand を使いストアドプロシジャーを実行して戻り値を DateSet にするような関数はプログラムを作っていくと、かなり多数になるようになりました。接続文字列だったり、いろいろ同じような記述が続いているなと思っておりました。 そこで、以下のような関数を作り、この部分を使いまわせないものかと思っております。 ストアドプロシジャーの名前や、そのほか必要な部分の文字はすべて変数にして、なんとか使えないのかなと思っているのですが、問題なのは、パラメータの部分でうまくいかないのです。 パラメータの部分だけ別関数にして、なんとかねじこめないかなと思っているのですが・・・ そもそもこういうやり方が正しいのかどうかもわからないのですが、その辺りも含めご教授いただければ幸いでございます。 何卒よろしくお願いいたします。 Public Function CommonDataSet(ByVal NameStored As String, ByVal CMDPara As SqlCommand, ByVal BasicTableName As String, ByVal ErrStr As String, ByVal ErrStrCaption As String) As DataSet     Dim SQLCon As SqlConnection = New SqlConnection(CMO.GetConnectStrings())     Try       CMDPara = New SqlCommand(NameStored, SQLCon)       CMDPara.CommandType = CommandType.StoredProcedure       SQLCon.Open()       Dim custDA As SqlDataAdapter = New SqlDataAdapter       Dim custDS As DataSet = New DataSet       ’この部分で下記の関数でパラメータを設定したいのですが、うまくいきません       custDA.SelectCommand = CMDPara       custDA.Fill(custDS, BasicTableName)       CommonDataSet = custDS     Catch ex As Exception       Err.Raise(Err.Number)       MessageBox.Show(ErrStr, ErrStrCaption, MessageBoxButtons.OK, MessageBoxIcon.Warning)       CommonDataSet = Nothing     End Try     If SQLCon.State <> ConnectionState.Closed Then       SQLCon.Close()       SQLCon.Dispose()     End If End Function パラメータを設定する関数 上の関数の引数として設定したいのです  ByVal CMDPara As SqlCommand の部分のパラメータとして Private Function CommonPara(CMD As SqlCommand) As SqlCommand     CMD.Parameters.Clear()     CMD.Parameters.Add(New SqlParameter(パラメータ1の記述)     CMD.Parameters.Add(New SqlParameter(パラメータ2の記述)     CMD.Parameters.Add(New SqlParameter(パラメータ3の記述)     CommonPara = CMD End Function

  • VBAでDBから取得したデータを突き合わせる

    VBAでOracleに接続し、取得したレコードを突き合せようとしています。 2つのテーブル(TBL_A、TBL_B)からレコードを1件ずつ取得し、 それぞれのレコードの項目を突き合わせて一致しているかを確認します。 2つのテーブルは以下のような状態です。 【TBL_A】 社員番号,SYAIN_NO,VARCHAR2(10) 社員名 ,SYAIN_NM,VARCHAR2(50) 【TBL_B】 社員番号,SYAIN_NO,VARCHAR2(10) 社員名 ,SYAIN_NM,VARCHAR2(50) レコードを取得する際、 以下のようなユーザ定義型変数に値を設定しています。 Dim TBL_A_REC As SYAIN Dim TBL_B_REC As SYAIN Type SYAIN SYAIN_NO As String SYAIN_NM As String End Type 今後、各テーブルに生年月日のカラム(BIRTH)を追加する可能性があり、生年月日も突き合わせたいです。 先日、こちらで質問してユーザ定義型変数を動的に増やすことは不可能であるとご回答を頂きました。 ユーザ定義型変数を用いずにDBから取得した値を設定し、 突き合わせを行う良い方法はあるのでしょうか?

  • MYSQLについて教えてください!

    お世話になります。 VB.net+MYSQLで開発してます。 MYSQLで聞きたいことがあるのですが、 今やろうとしている処理が 配列の要素数分ループ処理でインサートしようとしています。 しかし書き方が悪いのか配列名(カウンタ)という記述だと Functionに見られてしまいます。 それならと配列の要素を変数に代入して INSERTには変数をあてているのですが 変数が展開されません。。。 PHPとかだと変数の前に「.$」をつけると出来ると書いてあったのですが VBにも特殊なルールがあるのでしょうか? 以上よろしくお願いします。 以下サンプルソースです。(接続等はぶいてますが接続はできてます) Dim a As String Dim sqlstr As String Dim sqlcommand As Odbc.OdbcCommand for i as Integer = 0 to uBound(data_array) '初期化 a = "" '変数に値を設定 a = data_array(i) 'SQL文字列の設定 sqlstr = "insert into test( col_1 )" + _ "values(a);" sqlcommand.CommandText = sqlstr sqlcommand.ExecuteNonQuery() next

  • VB DB更新時にパラメーターへ値のセット

    データベースの更新についてご指導下さい。 VB2010からSQLサーバーのデータベースに接続しております。 dataAdapter.Updateによりデータベースを更新する際の パラメーターへ値をセットする方法を教えて下さい。 テーブル名Test Code Name ------------ A   Suzuki 希望する処理 テキストボックスに入力された名前に変更 例) Suzuki → Yamada ○フォームの変数として定義 Dim dataAdapter As New SqlDataAdapter Dim dataSet As New DataSet ○FormLoad時にSelectCommandとUpdateCommandを設定 Dim SQL As String = "" Dim command As SqlCommand Dim connection As SqlConnection = New SqlConnection(~) SQL = "SELECT * FROM Test WHERE Code = @code " command = New SqlCommand(SQL, connection) dataAdapter.SelectCommand = command dataAdapter.SelectCommand.Parameters.Add("@code", SqlDbType.Char) SQL = "UPDATE Test SET Name = @name WHERE Code = @code" command = New SqlCommand(SQL, connection) dataAdapter.UpdateCommand = command dataAdapter.UpdateCommand.Parameters.Add("@code", SqlDbType.Char) dataAdapter.UpdateCommand.Parameters.Add("@name", SqlDbType.Text, 50) ○データ表示時にはこれで表示されました。 dataAdapter.SelectCommand.Parameters.Item("@code").Value = ComboBoxCode.text dataAdapter.Fill(dataSet) ○このSelectCommandを参考にこのように書いて見たのですが更新されません。 dataAdapter.UpdateCommand.Parameters.Item("@code").Value = ComboBoxCode.Text dataAdapter.UpdateCommand.Parameters.Item("@name").Value = TextBoxName.Text dataAdapter.Update(dataSet) どのようにしたら実行時にパラメーター化したところへデータをセットできるのでしょうか? データセットに値が入っていないのでは?と予想したのですが…。