vb.net移行のoracle接続について

タグの編集
投稿者 abc  (社会人) 投稿日時 2023/8/10 11:43:38
vb6からvb.net(環境vb2022)に移行しています。
oracle接続の以下について教えてください。

vb6ではoracle inproc server 5.0 type libraryを参照追加
Public Session1 As OraSession
Public DB1 As OraDatabase

vb.netにマイグレーションすると以下になりエラー
Public Session1 As OracleInProcServer.OraSession
Public DB1 As OracleInProcServer.OraDatabase

OracleInProcServerが使えないのでOracle.ManagedDataAccessを参照追加

OraDatabaseはPublic DB1 As Oracle.ManagedDataAccess.Client.OracleConnectionで解決しました。
OraSessionの代替は何でしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/10 12:44:27
> vb6にはoracle inproc server 5.0 type libraryが参照追加されています。
いわゆる oo4o (Oracle Objects for OLE) のライブラリですね。

oo4o は Oracle 11g 時点でサポートが終了しており、
それ以降 (Oracle 12c / 18c / 19c / 21c / 23c) の Oracle Client には搭載されていません。

oo4o から、現行の Oracle Server に接続できない訳ではありませんが、
サポートとしては打ち切られています。


> vb.netにはOracle.ManagedDataAccessを参照追加しました。
そうですね。nuget で追加できますし、それがおすすめです。

.NET Framework が相手の場合は Oracle.ManagedDataAccess
.NET が相手の場合は Oracle.ManagedDataAccess.Core
を利用できます。これらは、ODP.NET (Oracle Data Provider for .NET) と呼ばれています。

ついでに、拡張機能の ODT (Oracle Developer Tools for Visual Studio) も入れておくと良いでしょう。
https://www.oracle.com/jp/database/technologies/developer-tools/visual-studio/


移植に当たって、まずは「ADO.NET」への理解が必須です(ODP.NET も ADO.NET の一種です)。

ADO.NET に関する知識をきちんと身に着けていないと、後々苦労することになりますので、
使い方を事前に学んでおきましょう。oo4o 時代のように Dynaset を開いて、
Delete / AddNew / Edit / Update するような開発スタイルでは無いですしね。


ADO.NET について説明しようとすると、それだけで本が一冊書けてしまう量になるので、
入門書、初心者向けサイト、チュートリアルの類を探してみてください。

ADO.NET では、接続先のデータベースによって、利用するクラスの名前空間が
Oracle.ManagedDataAccess
System.Data.OracleClient 
System.Data.SqlClient
System.Data.OleDb
System.Data.Odbc
などと変わりはしますが、どのデータベースであっても使用するメソッドはほぼ共通なので、
基本を押さえておくと、後々応用が利くかと思います。
(System.Data.Common を使うと、DbProviderFactories クラスによって、
 各種データベースへの接続部分を共通化することも可能です)


oo4o や RDO や DAO は、「利用中は、データベースへの接続を張ったままにする」実装ですが
ADO.NET は基本的に切断型であり「読み書きの瞬間だけ接続し、普段は切断状態」というスタイルです。

ちなみに VB6 の ADO (Active Data Objects) ライブラリは、
切断型での利用方法と、接続維持型での利用方法の両方に対応しています。



> モデュールに
「モジュール」ですね。


> 「BeginTrans」 「Rollback」 「.CommitTrans」 「CreateDynaset」
トランザクション制御には、大きく分けて 2 種類の方式があります。


・分散トランザクション:Using ステートメントで、System.Transactions.TransactionScope クラスを囲んで使う方法
 この方式では、複数データベースに対するデータ更新にも対応できます。
 Oracle 相手に利用する場合には、OraMTS がインストールされている必要があります。

Try
  Using scope As new TransactionScope()
    Using con As New OracleConnection(接続文字列)
      con.Open()
      Dim cmd = con.CreateCommand()
      cmd.CommandText = 更新SQL
      cmd.ExecuteNonQuery()
      con.Close()
    End Using
    scope.Complete()  'これが CommitTrans に相当します 
  End Using
Catch ex As Exception
  '例外処理などにより、Complete せずに破棄されると、自動的に Rollback されます 
  Debug.WriteLine(ex.ToString())
End Try



・ローカル トランザクション:Connection オブジェクトの BeginTransaction メソッドを使う方法
 Transaction オブジェクトの管理を手動で行う手法です。
 こちらは単一データベース接続のみが対象となります。
Using con As New OracleConnection(接続文字列)  '実際は接続失敗時の Try~Catch も必要 
  con.Open()
  Using txn As OracleTransaction = con.BeginTransaction(IsolationLevel.ReadCommitted)
    Try
      Dim cmd = con.CreateCommand()
      cmd.CommandText = 更新SQL
      cmd.ExecuteNonQuery()
      txn.Commit()  'これが CommitTrans 相当 
    Catch ex As Exception
      Debug.WriteLine(ex.ToString())
      txn.Rollback()  'これが Rollback 相当 
    End Try
  End Using
End Using



> また、OraSessionの代替は何でしょうか。
接続プールの概念はありますが、考え方が違うのでそのものズバリはありません。
OracleConnection をそのままお使いください。

Dyanset に直接あたるものは無いので、
 DataAdapter + DataSet
を使うことが多いです。
型付 DataSet の場合は TableAdapter がこれにあたります。

更新無しの ORADYN_NOCACHE かつ ORADYN_READONLY な Dynaset の場合
OracleCommand の ExecuteReader メソッドを使います。
(DataSet を経由するよりも高速に読み取れます)
なお、この目的の場合は Dapper というライブラリで提供される拡張メソッドを併用するのが便利です。
投稿者 abc  (社会人) 投稿日時 2023/8/10 14:43:07
魔界の仮面弁士さん

多くの有益な情報をありがとうございます。
大変参考になりました。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/10 17:36:10
失礼しました。

自分の投稿をよく読み直してみると、
> 投稿者 abc   (社会人)   投稿日時 2023/8/10 10:43:55 ※ThreadId=30888
宛に回答したつもりで、誤って
> 投稿者 abc   (社会人)   投稿日時 2023/8/10 11:43:38 ※ThreadId=30889
宛に回答してしまっていたようです。

引用した文章が多少違ってしまいましたが、内容的には大差無いのでご容赦を…。