🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

4413閲覧

データテーブルを行ループさせながら 更新を達成したい

saya24

総合スコア246

DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2021/03/02 09:40

編集2021/03/02 10:20

Microsft SQLServerのある一つのテーブルについて、Oracle上の別テーブルの状況次第で 更新していく作業を達成しようとしています。
(いつもはSQLServerの接続はSystem.Data.SqlClientを利用するのですが 試行錯誤しているうちにOLEDBプロバイダになってしまいました...。プロバイダに拘りはありません)

『質問』

以下現在取り組んでいるコードの抜粋ですが、
「この Command に関連付けられている DataReader が既に開かれています。このコマンドを最初に閉じる必要があります。」というエラーを招いてしまいます。
接続を維持して、別データを参照し 元データ(テーブル)の更新を行う方法は どうするのが鉄板・常套手段でしょうか?
今朝方 ADO.NETのDataAdapter・DataSet・DataTableで トライしていたのですが、元データのループを形成しようとデータセットを作る部分で やはりコネクションを閉じることになってしまい ダメだ~ と諦めてしまいました。

なんか参考になる記事の紹介でも結構です。どういう手続きを行えばよいか ヒントを頂けないでしょうか

VB

1Try 2 Dim prov As String = "XXX" 3 Dim serverName As String = "XXX" 4 Dim dataBase As String = "XXX" 5 Dim userid As String = "XXX" 6 Dim pwd As String = "XXX" 7 8 Using conn As New OleDb.OleDbConnection() 9 Using cmd1 As New OleDb.OleDbCommand() 10 conn.ConnectionString = 11 " Provider = " & prov & 12 ";Data Source = " & serverName & 13 ";Initial Catalog = " & dataBase & 14 ";User ID = " & userid & 15 ";Password =" & pwd 16 17 Dim dr As OleDbDataReader = Nothing 18 cmd1.Connection = conn 19 conn.Open() 20 21 cmd1.CommandText = "SELECT * FROM SFA51 WHERE CHK_FLG IS NULL" 22 dr = cmd1.ExecuteReader() 23 While (dr.Read()) 24 Dim SqlString1 As String = "SELECT * FROM 取引先 WHERE コード='" & dr.Item(9) & "'" 25 26 Using cn As New OracleConnection(CnString) 27 cn.Open() 28 Using cmd2 As New OracleCommand 29 Dim rd As OracleDataReader = Nothing 30 cmd2.Connection = cn 31 cmd2.CommandText = SqlString1 32 rd = cmd2.ExecuteReader 33 If rd.Read Then 34 Else 35 GoTo next_rec 36 End If 37 38 Try 39 '検疫OKの証を SFA51テーブル上のチェックフラグに更新 40 cmd1.CommandText = "UPDATE SFA51 SET CHK_FLG=2, CHK_TIMESTAMP=CURRENT_TIMESTAMP WHERE APPNO=? AND APPLINEO=?" 41 42 cmd1.Parameters.Add("@APPNO", OleDb.OleDbType.VarChar).Value = dr.Item(0) 43 cmd1.Parameters.Add("@APPLINENO", OleDb.OleDbType.VarChar).Value = dr.Item(1) 44 cmd1.ExecuteNonQuery() 45 Catch ex As Exception 46 System.Diagnostics.Debug.Print(ex.Message ) '★エラー表示部分★ 47 End Try 48 If Not rd Is Nothing Then 49 rd.Close() 50 End If 51 52 End Using 53 cn.Close() 54 55 End Using 56next_rec: 57 End While 58 59 60 End Using 61 62 End Using 63 64Catch ex As Exception 65 Console.WriteLine(ex.Message) 66 67End Try

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/02 15:57 編集

エラーを載せるときはエラーメッセージだけではなく、なるべくExceptionオブジェクトのクラス名やStackTraceを含めてください。ExceptionオブジェクトをToStringするだけでも、かなり詳細な情報が取り出せます。
saya24

2021/03/03 00:32

オブジェクトをToStringして 出力するようにした方が良い、とのアドバイスありがとうございました。今後の為に価値あるご指摘です。 なんとなく自分が悩んでいる根幹の理由を突きつめられた気がします。 コマンドオブジェクトのUsingの中でリーダをループさせる事例ばかりを目にしてきているので、UPDATE用に別のコマンドオブジェクトを生成する手法では リーダーを回せないという意識があったのだと思います。 元のコマンドオブジェクトのUsingの中で、Using無しに新たコマンドオブジェクトを生成して利用するか、Usingを入れ子にすれば良いのですね、多分。 コマンドオブジェクトのUsingの中でリーダーをループさせている例。https://itsakura.com/vbnet-sqlserver-select
退会済みユーザー

退会済みユーザー

2021/03/03 00:39

そもそもDataReaderで使用中のCommandオブジェクトで別のSQL文を実行させたらまずいです。 別のCommandオブジェクトを作成してください。
saya24

2021/03/03 01:40

了解です、初歩的なことかも知れなかったですが 親切に教えて頂きありがとうございました。いつまでたってもコピぺで対応し 仕組みの理解に努めないと ダメなんだなぁ と実感いたしました。 本件クローズとします。
guest

回答2

0

リンクサーバーを経由すれば、SQLServerへの接続だけで、oracleのテーブルも参照できます。
Oracle データベースへのリンク サーバーのセットアップとトラブルシューティング

投稿2021/03/02 10:54

sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2021/03/02 13:27

saziさん いつもお世話になっております。リンクサーバでは いい思いしたことがないので 今回はデータベース側ではない解決策を目指していきます。ご見解ありがとうございました。
guest

0

ベストアンサー

接続を維持して、別データを参照し 元データ(テーブル)の更新を行う方法は どうするのが鉄板・常套手段でしょうか?

先に別データをDataTableなりに取り出しておいたらダメですか?

cmd1.Parameters.Add("@APPNO", OleDb.OleDbType.VarChar).Value = dr.Item(0) cmd1.Parameters.Add("@APPLINENO", OleDb.OleDbType.VarChar).Value = dr.Item(1)

直接DataReaderのオブジェクトをValueに設定してるのがまずそうな感じがしますが、dr.Item(0)を一旦ToStringするとどうなりますかね?


(追記)
よく見ると、updateがselectと同じCommandオブジェクト(cmd1)で実行されているので、これが原因に見えます。update用に別に作成するだけで解決しそうな気がします。

投稿2021/03/02 10:47

編集2021/03/02 15:57
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2021/03/02 13:25

radianさん ご見解ありがとうございます。早々にパラメータの指定方法を変えて検証したいのですが 現在データベースに繋げない状況にあります。結果がでたら ご報告改めます。 それだけで結果が良い方向に向かうと うれしいのですが....
saya24

2021/03/03 01:41

別のコマンドオブジェクトを生成して UPDATE文を発行する作りに変えて 無事動作するようになりました。radianさん 親切な導きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問