C#からOracle 18c XEへODP.NETで接続

CentOS 7.6にOracle 18c XEをインストール。
外部接続できるよう構成しました。
Oracle Database Express Edition (XE) 18cをCentOS 7.6にインストール
Oracle 18c XE 外部接続を許可する(別端末からの接続)

この環境にC#から接続してみます。
OSはWindows 10です。


.Net Provider



接続用のドライバを取得します。
NuGetで取得もできますが、
Oracle.ManagedDataAccess
offlineの場合も考慮し、今回はインストーラーでインストールしました。

こちらから「ODTwithODAC183.zip」をダウンロード。
https://www.oracle.com/technetwork/topics/dotnet/downloads/index.html

996_01.png

996_02.png


ODTwithODAC183.zipを解答し、setup.exeを実行します。

996_03.png

中身のdllを取り出したいだけなので、インストーラーはデフォルトのまま進めます。

996_04.png

996_05.png

「インストール場所の指定」で「ソフトウェア場所」を控えておきます。

996_06.png

「Oracle Data Provider for .NET」が選択されていることを確認して次へ。

996_07.png

996_08.png

996_09.png

996_10.png

これでインストールは完了です。

996_11.png





dllの取得



「インストール場所の指定」で「ソフトウェア場所」に指定したフォルダを開きます。
開いたフォルダの中の
odp.net\managed\commonに「Oracle.ManagedDataAccess.dll」があります。
これが接続ライブラリになります。

996_12.png

このdllをこれから作成するソースファイルと同じ階層に保存しておきます。





接続文字列



今回のデータベースの設定は以下のとおり。


ID:orauser
Password:Passw0rd
HOST:192.168.1.104
PORT:1521
SERVICE_NAME:xepdb1



接続文字列はこうなります。


User ID=orauser;
Password=Passw0rd;
Data Source=
(DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = 192.168.1.104)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = xepdb1)));






サンプル



サンプルは以下のようになりました。

・Sample.cs


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using Oracle.ManagedDataAccess.Client;
  5.     
  6. public class Sample {
  7.         
  8.     [STAThread]
  9.     public static void Main(string[] args) {
  10.         
  11.         OracleConnection con = new OracleConnection();
  12.         string dataSource = "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = 192.168.1.104)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = xepdb1)))";
  13.         
  14.         con.ConnectionString = "User ID=orauser; Password=Passw0rd; Data Source=" + dataSource + ";";
  15.         con.Open();
  16.         
  17.         string sql = "SELECT * FROM sample";
  18.         OracleCommand cmd = new OracleCommand(sql, con);
  19.         
  20.         OracleDataReader reader = cmd.ExecuteReader();
  21.         while ( reader.Read() ) {
  22.             Console.WriteLine(string.Format("{0}:{1}", reader["id"], reader["val"]));
  23.         }
  24.         
  25.         reader.Close();
  26.         con.Close();
  27.         
  28.     }
  29. }





統合開発環境をインストールしていないので、こんなバッチファイルを作成してコンパイルしました。

・build.bat


@echo off
set csc="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
set opt=/nologo
set recurse=/r:Oracle.ManagedDataAccess.dll

%csc% %opt% %recurse% Sample.cs




コンパイル&実行してみます。

996_13.png

無事動いてくれました。



DataAdapterを使用したサンプル



DataReaderではなくDataAdapterを使用したサンプルはこのようになりました。


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using Oracle.ManagedDataAccess.Client;
  5.     
  6. public class Sample {
  7.         
  8.     [STAThread]
  9.     public static void Main(string[] args) {
  10.         
  11.         OracleConnection con = new OracleConnection();
  12.         string dataSource = "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = 192.168.1.104)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = xepdb1)))";
  13.         
  14.         con.ConnectionString = "User ID=orauser; Password=Passw0rd; Data Source=" + dataSource + ";";
  15.         con.Open();
  16.         
  17.         string sql = "SELECT * FROM sample";
  18.         OracleCommand cmd = new OracleCommand(sql, con);
  19.         
  20.         /* DataReaderを使用
  21.         OracleDataReader reader = cmd.ExecuteReader();
  22.         while ( reader.Read() ) {
  23.             Console.WriteLine(string.Format("{0}:{1}", reader["id"], reader["val"]));
  24.         }
  25.         
  26.         reader.Close();
  27.         */
  28.         // DataAdapterを使用
  29.         OracleDataAdapter adapter = new OracleDataAdapter(cmd);
  30.         DataSet ds = new DataSet();
  31.         adapter.Fill(ds);
  32.         foreach(DataRow dr in ds.Tables[0].Rows) {
  33.             Console.WriteLine(string.Format("{0}:{1}", dr["id"], dr["val"]));
  34.         }
  35.         con.Close();
  36.         
  37.     }
  38. }



実行結果はDataReaderの時と同様です。

【参考URL】
C#からOracle 11g XEへODP.NETで接続

Ubuntu 18.04 + cx_OracleでPythonからOracle 18c XEへ接続する

Oracle 18cのドキュメントを見ていると
Oracle Database XE Quick Start

cx_OracleでPythonからOracleに接続できるようです。
cx_Oracle version 7.1

早速試してみます。


インストール



今回はPython3で動作を確認します。
pip3でcx_Oracleをインストール。


$ pip3 install cx_Oracle --upgrade



7.1.3がインストールできました。



Instant Client Downloads for Linux x86-64 (64-bit)



cx_Oracle、簡単にインストールできたなと思い動かしてみるとこんなエラー。


cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library:
"libclntsh.so: cannot open shared object file: No such file or directory".
See https://oracle.github.io/odpi/doc/installation.html#linux for help



cx_Oracleのドキュメントを見てみると、別途クライアントライブラリのインストールが必要なようです。
Oracle Instant Client Zip Files

こちらから、instantclient-basic-linux.x64-19.3.0.0.0dbru.zipをダウンロード。
Instant Client Downloads for Linux x86-64 (64-bit)

994_01.png

手順に従い、/opt/oracleを作成して展開します。


$ sudo mkdir -p /opt/oracle
$ sudo mv instantclient-basic-linux.x64-19.3.0.0.0dbru.zip /opt/oracle
$ cd /opt/oracle
$ sudo unzip instantclient-basic-linux.x64-19.3.0.0.0dbru.zip



これで/opt/oracle/instantclient_19_3にライブラリが展開されました。


libaioが必要とのことなのでインストールしておきます。


$ sudo apt install libaio1



展開したライブラリのパスを/etc/ld.so.conf.d/に追加


$ sudo sh -c "echo /opt/oracle/instantclient_19_3 > /etc/ld.so.conf.d/oracle-instantclient.conf"
$ sudo ldconfig



これで準備は整いました。




文字化け



簡単なサンプルを実行してみます。


  1. import cx_Oracle
  2. # Connect string format: [username]/[password]@//[hostname]:[port]/[DB service name]
  3. conn = cx_Oracle.connect("orauser/Passw0rd@//192.168.1.104:1521/xepdb1")
  4. cur = conn.cursor()
  5. cur.execute("select * from sample")
  6. for row in cur:
  7.     print(row[0], row[1])




文字化けしました。


$ python3 sample.py
1 ?????
2 Java????




こちらを参考に「NLS_LANG」を設定してやります。
PythonからOracleへ接続してみる

設定値は、
Oracle Database XE 18c sqlplusの文字化けに対応し、日本語表示
こちらで指定した「Japanese_Japan.AL32UTF8」としました。


  1. import os
  2. import cx_Oracle
  3. os.environ["NLS_LANG"] = "Japanese_Japan.AL32UTF8"
  4. # Connect string format: [username]/[password]@//[hostname]:[port]/[DB service name]
  5. conn = cx_Oracle.connect("orauser/Passw0rd@//192.168.1.104:1521/xepdb1")
  6. cur = conn.cursor()
  7. cur.execute("select * from sample")
  8. for row in cur:
  9.     print(row[0], row[1])




文字化け無しで表示できました。


$ python3 sample.py
1 登録テスト
2 Javaから登録






【参考URL】
PythonからOracleへ接続してみる

ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

Oracle 18c XEへJava(JDBC)で接続
こちらを試している時、タイトルのエラーが発生しました。


java.sql.SQLException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor



ソースはこちら。


  1. package com.fc2.blog.symfoware;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class MainProcess {
  7.     public static void main(String... args) {
  8.         String url = "jdbc:oracle:thin:@192.168.1.104:1521:xepdb1";
  9.         String user = "orauser";
  10.         String pass = "Passw0rd";
  11.         try (Connection con = DriverManager.getConnection(url, user, pass);
  12.                 Statement stmt = con.createStatement();
  13.                 ResultSet rs = stmt.executeQuery("select * from sample");) {
  14.             while (rs.next()) {
  15.                 System.out.println(rs.getInt("id"));
  16.                 System.out.println(rs.getString("val"));
  17.             }
  18.         } catch (Exception e) {
  19.             e.printStackTrace();
  20.         }
  21.     }
  22. }



何が悪いのかさっぱりわからん。



接続文字列



最初、サーバー側のリスナー登録がまずいのかと思いましたが、オチは簡単でした。
接続文字列が間違っています。

間違い

jdbc:oracle:thin:@192.168.1.104:1521:xepdb1



正解

jdbc:oracle:thin:@192.168.1.104:1521/xepdb1



ポート番号とDB service nameの区切りは「/」です。

修正したらあっさりつながりました。


  1. package com.fc2.blog.symfoware;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class MainProcess {
  7.     public static void main(String... args) {
  8.         String url = "jdbc:oracle:thin:@192.168.1.104:1521/xepdb1";
  9.         String user = "orauser";
  10.         String pass = "Passw0rd";
  11.         try (Connection con = DriverManager.getConnection(url, user, pass);
  12.                 Statement stmt = con.createStatement();
  13.                 ResultSet rs = stmt.executeQuery("select * from sample");) {
  14.             while (rs.next()) {
  15.                 System.out.println(rs.getInt("id"));
  16.                 System.out.println(rs.getString("val"));
  17.             }
  18.         } catch (Exception e) {
  19.             e.printStackTrace();
  20.         }
  21.     }
  22. }


Oracle 18c XEへJava(JDBC)で接続

CentOS 7.6にOracle 18c XEをインストール。
Oracle Database Express Edition (XE) 18cをCentOS 7.6にインストール

別の端末から接続できるようにしました。
Oracle 18c XE 外部接続を許可する(別端末からの接続)

この環境にJavaからJDBC経由で接続してみます。
11gの時の手順を参考にしています。
Oracle 11g XEへJava(JDBC)で接続


JDBCドライバの取得



こちらから取得しました。
Oracle Database 18c (18.3) JDBC Driver & UCP Downloads

993_01.png

Oracleプロファイルへのサインインを求められるので、ID・パスワードを入力。
「ojdbc8.jar」をダウンロードしました。
ビルドパスに含めておきます。

993_02.png




検索サンプル



データベースへの接続と検索のサンプルです。


  1. package com.fc2.blog.symfoware;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class MainProcess {
  7.     public static void main(String... args) {
  8.         
  9.         String url = "jdbc:oracle:thin:@192.168.1.104:1521/xepdb1";
  10.         String user = "orauser";
  11.         String pass = "Passw0rd";
  12.         try (Connection con = DriverManager.getConnection(url, user, pass);
  13.                 Statement stmt = con.createStatement();
  14.                 ResultSet rs = stmt.executeQuery("select * from sample");) {
  15.             
  16.             while (rs.next()) {
  17.                 System.out.println(rs.getInt("id"));
  18.                 System.out.println(rs.getString("val"));
  19.             }
  20.         } catch (Exception e) {
  21.             e.printStackTrace();
  22.         }
  23.     }
  24. }



実行すると、テストで登録しておいた値が取得できました。


1
登録テスト





登録サンプル



データの登録を実行して検索してみます。


  1. package com.fc2.blog.symfoware;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class MainProcess {
  7.     public static void main(String... args) {
  8.         String url = "jdbc:oracle:thin:@192.168.1.104:1521/xepdb1";
  9.         String user = "orauser";
  10.         String pass = "Passw0rd";
  11.         try (Connection con = DriverManager.getConnection(url, user, pass);
  12.                 Statement stmt = con.createStatement();) {
  13.             // 登録実行
  14.             stmt.execute("insert into sample (id, val) values (2, 'Javaから登録')");
  15.             ResultSet rs = stmt.executeQuery("select * from sample");
  16.             while (rs.next()) {
  17.                 System.out.println(rs.getInt("id"));
  18.                 System.out.println(rs.getString("val"));
  19.             }
  20.         } catch (Exception e) {
  21.             e.printStackTrace();
  22.         }
  23.     }
  24. }



実行結果


1
登録テスト
2
Javaから登録


Oracle 18c XE 外部接続を許可する(別端末からの接続)

CentOS 7.6にOracle 18c XEをインストールしてみました。
Oracle Database Express Edition (XE) 18cをCentOS 7.6にインストール

別の端末から接続できるよう構成してみます。


firewalldのポートを開ける



といっても、ファイアウォールのtcp:1521ポートを開けるだけです。


# firewall-cmd --zone=public --add-port=1521/tcp --permanent



reloadで反映


# firewall-cmd --reload




設定が反映されたか確認してみます。


# firewall-cmd --list-all



992_01.png

これで別の端末から接続できるようになりました。


【参考URL】
Centos7 でポートを開放する方法:コマンドとファイル書き込み

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ