0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C#でODP.NETの自己流便利クラス(Bind変数利用)

Last updated at Posted at 2019-09-27

概要

C#でODP.NETを使おうと思ったら大変だったので記事に残します。
自己流の自分用便利クラスなのでベストプラクティスは他にあると思います。
※環境はVisualStudio2019です

流れ

Oracle.ManagedDataAccsessのインストール
Oracleとの接続設定
Oracle操作用便利クラスの作成
便利クラスの使い方

Oracle.ManagedDataAccsessのインストール

プロジェクトを右クリックし、「NuGet パッケージの管理(N)...」を選択
参照で「Oracle.ManagedDataAccsess」を検索し、インストール

Oracleとの接続設定

いくつか方法があるようですが、今回はApp.Configを利用します。
Oracle.ManagedDataAccsessをインストールした時点でが生成されています。
そこに必要な情報を入力してください。
○○○:エイリアス
△△△:DBサーバーのホスト名orIPアドレス

※ここに入力する内容は、tnsnames.oraに登録してある内容と同じです。
※dataSources内には複数のdataSourceを入れることができます。

<oracle.manageddataaccess.client>
    <version number="*">
      <dataSources>
        <dataSource alias="○○○"
                descriptor="(DESCRIPTION = (ADDRESS = (PROTOCOL = tcp)(HOST = △△△)(PORT = 1521))(CONNECT_DATA = (SERVICE_NAME = orcl))) "/>
      </dataSources>
    </version>
</oracle.manageddataaccess.client>

Oracle操作用便利クラスの作成

あくまで自己流なので、より良い方法があれば教えてください。
一応Transactionも考慮しています。(未検証)

using Oracle.ManagedDataAccess.Client;
using System;

namespace common {
    class DbControl {

        // DB接続
        private OracleConnection conn;

        // SQL発行に必要
        private OracleCommand cmd;

        // SELECT時の結果読み取りに利用
        private OracleDataReader reader;

        // Transactionに利用
        private OracleTransaction transaction;

        // Bind変数に利用する型
        public static int DATE = 0;
        public static int VARCHAR2 = 1;
        public static int DOUBLE = 2;
        public static int INT16 = 3;
        public static int INT32 = 4;

        /// <summary>
        /// コンストラクタ:iniファイルから取得した情報でDBと接続し、接続(OracleConnection)を保持する
        /// </summary>
        public DbControl() {
            string connectString = "user id = " + Main.OracleLogonName + "; password = " + Main.OraclePassWord + "; data source = " + Main.OracleDbName;

            try {
                conn = new OracleConnection(connectString);
                conn.Open();
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
                conn.Close();
            }
        }

        /// <summary>
        /// SQL文を使用し、OracleCommandを作成する
        /// <para>string sql:assets/sqlから取得したSQL文の文字列</para>
        /// </summary>
        public void SetCommand(string sql) {
            cmd = new OracleCommand(sql, conn);
            // バインド変数の名前解決
            cmd.BindByName = true;
        }

        /// <summary>
        /// バインド変数の設定
        /// <para>string parameterName:カラム名</para>
        /// <para>object parameterValue:カラムの値。string、DateTime等を渡す</para>
        /// <para>int oracleDbType:カラムのデータタイプ指定。DbManagementの定数を渡す</para>
        /// </summary>
        public void SetBindVariable(string parameterName, object parameterValue, int oracleDbType) {
            OracleParameter dbParameter = cmd.CreateParameter();
            switch (oracleDbType) {
                case 0:
                    dbParameter.OracleDbType = OracleDbType.Date;
                    break;
                case 1:
                    dbParameter.OracleDbType = OracleDbType.Varchar2;
                    break;
                case 2:
                    dbParameter.OracleDbType = OracleDbType.Double;
                    break;
                case 3:
                    dbParameter.OracleDbType = OracleDbType.Int16;
                    break;
                case 4:
                    dbParameter.OracleDbType = OracleDbType.Int32;
                    break;
            }
            dbParameter.ParameterName = parameterName;
            dbParameter.Value = parameterValue;
            cmd.Parameters.Add(dbParameter);
        }

        /// <summary>
        /// Transaction:開始(成功すればCommitを呼び、失敗したらRollBackを呼ぶ必要がある)
        /// </summary>
        public void BeginTransaction() {
            transaction = conn.BeginTransaction();
        }

        /// <summary>
        /// Transaction:コミット
        /// </summary>
        public void Commit() {
            transaction.Commit();
        }

        /// <summary>
        /// Transaction:ロールバック
        /// </summary>
        public void RollBack() {
            transaction.Rollback();
        }

        /// <summary>
        /// SELECT系のSQLで使用
        /// <returns>return OracleDataReader:</returns>
        /// </summary>
        public OracleDataReader ExecuteReader() {
            try {
                reader = cmd.ExecuteReader();
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
            }
            return reader;
        }

        /// <summary>
        /// 実行系のSQLで使用
        /// <returns>return Boolean:</returns>
        /// </summary>
        public Boolean ExecuteNonQuery() {
            int res = 99;
            try {
                res = cmd.ExecuteNonQuery();
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
            }
            if (res >= 1) {
                return true;
            } else {
                return false;
            }
        }

        /// <summary>
        /// DBのコネクションを閉じる(readerがあればreaderも)
        /// </summary>
        public void Close() {
            // 実行系だとnullになる為
            if (reader != null) {
                reader.Close();
            }
            conn.Close();
        }

        // 
        public static String GetString(OracleDataReader read, string target) {
            if (read.GetValue(read.GetOrdinal(target)).ToString() == "") {
                return "";
            } else {
                return read.GetString(read.GetOrdinal(target));
            }
        }

        // 
        public static int GetInt16(OracleDataReader read, string target) {
            return read.GetInt16(read.GetOrdinal(target));
        }

        // 
        public static int GetInt32(OracleDataReader read, string target) {
            return read.GetInt32(read.GetOrdinal(target));
        }

        // 
        public static float GetFloat(OracleDataReader read, string target) {
            return read.GetFloat(read.GetOrdinal(target));
        }

        // 
        public static String GetDateString(OracleDataReader read, string target, string format) {
            if (read.GetValue(read.GetOrdinal(target)).ToString() == "") {
                return "";
            } else {
                return read.GetDateTime(read.GetOrdinal(target)).ToString(format);
            }
        }
    }
}

便利クラスの使い方

SELECTしてみる

string sql = "SELECT name FROM Something WHERE hobby = :hobby;";

DbControl dbControlt = new DbControl();
dbControlt.SetCommand(sql);
// 第一引数はBind変数、第二引数は値、第三引数はカラムの型に合わせたもの
dbControlt.SetBindVariable("hobby", "山登り", DbControl.VARCHAR2);

OracleDataReader reader = dbControlt.ExecuteReader();
if (reader != null) {
  if (reader.HasRows) {
    while (reader.Read()) {
      Console.WriteLine(DbControl.GetString(reader, "name"));
    }
  }
}      

DbControl.Close();         

UPDATEしてみる

string sql = "UPDATE Something SET hobby = :hobby WHERE name = :name;";

DbControl dbControlt = new DbControl();
dbControlt.SetCommand(sql);
dbControlt.SetBindVariable("hobby", "川登り", DbControl.VARCHAR2);
dbControlt.SetBindVariable("name", "田中", DbControl.VARCHAR2);

OracleDataReader reader = dbControlt.ExecuteReader();
if (dbManagement.ExecuteNonQuery()) {
  Console.WriteLine("成功");
}else{
  Console.WriteLine("失敗");
}

DbControl.Close();
0
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?