- ベストアンサー
VB.NETからAccessテーブルの文字列を操作する際・・
VB2005からAccessのmdbのテーブルのあるカラムより数バイトを切り出して別のカラムにコピーするだけの単純なプログラムなのですが、以下のように30バイトや34バイトで切り出しているにもかかわらず16バイトしか入ってきません。 cn.ConnectionString = "Provider= Microsoft.Jet.OLEDB.4.0;" _ & "Data Source = d:\csmain\cstool\egz0omen.mdb" cn.Open() com = cn.CreateCommand() com.CommandText = "select カラムA from T_テーブル" dread = com.ExecuteReader Do While (dread.Read()) com = New OleDb.OleDbCommand("update T_テーブル set カラムB = LeftB(カラムA, 30), " _ & " カラムC = LeftB(カラムA, 34) , " _ & " カラムE = LeftB(カラムA, 36) ") com.Connection = cn com.ExecuteNonQuery() Loop <実行結果> カラムA 123456789012345 カラムB~カラムE全て 12345678 試しにバイト数を10バイトずつ増やして、30→40、34→44、36→46にしても結果は同じでした。 宜しくお願い致します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
ADO.NETでは、旧ADOのような、「カラム別に編集して1レコードずつUpdateメソッドで簡単に更新」 といった処理は出来ません。少なくともDataReaderでは無理です。 (DataAdapter、DataSetを使えば似たようなことは出来ますが、あちらは プログラムから単純に見たら、基本的に一括更新です) で、今回の形でやるなら、結局UpdateのSQL Commandを実行するしか ないと思いますが、そこで気になることが2つ。 1.SQLにLeftBなんて関数は存在しません。 割と多くの初心者が勘違いされるようなんですが、SQL文は、あくまで 「DBに渡す、DB用の命令を記述した、ただの文字列」です。 SQL文の中に、VB内で使用している変数名を直接書いたり、VBの関数を 直接書いたりしても、勝手に置き換えたりは してくれません。 LeftBに類似したSQL関数は、DBによっては存在しますが、Accessだと無理っぽいですね。 (後述の通り、VB2005にもLeftBは無いんですけどね) 2.SQL Update文に、WHERE句がありません。 ループして1レコードずつ更新するなら、あくまで1回ごとのUpdate文の中で、 更新対象のレコードを指定するWHERE句が必要です。 使用するSQL文は、各カラムがテキスト型だとすると、 "update T_テーブル set カラムB = '" & _ LeftB(カラムA, 30) & "', カラムC = '" & _ LeftB(カラムA, 34) & "'," カラムE = '" & _ LeftB(カラムA, 36) & "' WHERE (検索条件はご自分で設定してください)" みたいな感じかな? (数値型の場合は、シングルクオートの編集を外してください) なお、VB2005にLeftB関数は存在しませんので、自作する必要があります。 (やり方としては、Shift-JISにエンコードしてから切り出して、Unicodeに戻すんだけど… これについては、検索すればどこかにあるんじゃないかな) 余談ですが、ADO.NETについて踏み込んで勉強したい場合は、参考URLあたりが 結構いいと思います。多少難解ですが。
その他の回答 (1)
- fumufumu_2006
- ベストアンサー率66% (163/245)
とりあえず質問のプログラムを見た感想ですが・・・ 「カラム」というと勘違いしそうなので、フィールドとレコードで話をさせてもらいます。 カラムAからカラムEというフィールドを持つ全レコードに対して行う操作なのなら・・・ そのSQLは1度で全てのレコードに対してupdateを行うので、Do...loop内で複数回実行しているのはおかしいような気がします。 あるフィールドに対して、各レコードをカラムAからカラムEと言うのなら・・・ SQL文がおかしいような気がします。
補足
ご回答ありがとうございます。 確かにご指摘のとおりSQL文がおかしいです。 中略していますが、1レコードずつ読み込む必要がありますので Do..Loopは必要ですが、UPDATEである必要は全くありませんでした。 カラムB=LeftB(カラムA,30)のような代入式でよいのですが、 試してみるとやはり、com.ExecuteNonQueryでSQL文でないためエラーが出ます。 代入式でよい場合はどのようにしたらよいかご存知でしょうか?
お礼
連絡大変遅くなりました。 ご指摘のとおりUPDATE文がおかしく、ループごとに全件レコード更新していたため、最終レコードの文字列のバイト数で更新されておりました。 それとLEFTB関数も確かにうまくいかずLEFT関数なら正常にいきました。 どうもありがとうございました。