株式会社アシスト
竹内 尚也
2
自己紹介
● 竹内 尚也
元々Oracleの仕事をしていましたが、1年半前ほどか
らPostgreSQLチームへ配属。普段はOracleから
PostgreSQLへの移行に関する問い合わせがメインで
す。
3
アジェンダ
1.はじめに
2.Javaから接続
3.C# (.NET系) から接続
4.おわりに
4
1. はじめに
PostgreSQLへ接続する
Javaのコード作って
いいよ
(Java歴1年)
5
1. はじめに
PostgreSQLへ接続する
C#のコード作って
…
(C#歴0年)
作って
いいよ
6
1. はじめに
ついでにVBからの
接続方法も
調べるか。
後、ODBC使って
エクセルからも
接続できないかな。
流行りのPythonからも
接続できるのかな?
調べてみたい。
7
1. はじめに
色々な言語からPostgreSQLへ
接続してきたけど、その諸々を
改めて整理してみる。
8
2.Javaから接続
JDBC (Javaの機能) によりPostgreSQLへ接続
Javaアプリケーション
JDBC
JDBCドライバマネージャ
データベースAの
JDBCドライバ
データベースBの
JDBCドライバ
(クライアント側)
(DB側)
データベースA データベースB
9
2.Javaから接続
実際にコードを書いて接続検証してみた。
●用意するもの
● PostgreSQL
● Javaの環境と接続先DBのJDBCドライバ
 DBサーバ
● CentOS 7.3
● PostgreSQL 10.1
 クライアントサーバ
● Windows 10
● Java 1.8
● JDBCドライバ 4.2
<検証環境>
10
2.Javaから接続
実際に書いて接続してみた。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Sample_pos_conn {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
//接続文字列
String url = "jdbc:postgresql://123.45.67.89:5432/postgres";
String user = "postgres";
String password = "password";
try{
Class.forName("org.postgresql.Driver");
//PostgreSQLへ接続
conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
…
雰囲気を
感じてもらえれば・・・
11
2.Javaから接続
実際に使う時の注意点的な何か。
●接続文字列
jdbc:postgresql://DB側のIP or ホスト名:ポート番号/DB名
●forName (ドライバの初期化)
try{
Class.forName("org.postgresql.Driver");
…
catch (ClassNotFoundException e){
…
データベース毎に記述の仕方が違う!
12
2.Javaから接続
実際に使う時の注意点的な何か。
●トランザクション処理
JDBCはデフォルトで自動コミットがONになっている。
※JDBC側の機能なため、DBに依らず自動コミットとなる。
自動コミットをOFFにした場合、SQL開始時に自動でBEGINを
入力してくれる。
…
自動コミットOFF
…
INSERT INTO
jdbc_tes VALUES (1);
…
初のSQLキタ!
BEGIN付けて
DBに送ったろ!!
INSERT INTO
jdbc_tes VALUES (1);
BEGIN;
データベース
13
2.Javaから接続
実際に使う時の注意点的な何か。
●トランザクション処理
ただしどのようなSQLが来てもBEGINを自動実行するため、
明示的にBEGINを入力すると、2重のBEGINが実行される。
…
自動コミットOFF
…
BEGIN;
…
初のSQLキタ!
BEGIN付けて
DBに送ったろ!!
BEGIN;
BEGIN;
データベース
WARNING: there is already a transaction in progress
※ちなみにCOMMIT、ROLLBACKはJavaの関数があるので、
 明示的にSQL文を書く必要はない。
14
3.C# (.NET系) から接続
.NETの外部ライブラリであるNpgsqlにより接続
またはODBCによる接続
※個人的にODBCは古いのでしか使われてないイメージ。
ODBCはエクセルとかから接続するのに
使われる方が多いのかな?
画面が寂しかったので、
使い所のないと評判のイラストを貼る→
15
3.C# (.NET系) から接続
実際にコードを書いて接続検証したかったけど…
パソコン新しくしたから、
昔作ったNpgsql環境ないじゃん。
一から作り直さないと
「Npgsql ダウンロード」を検索
実際にコードを書いて接続検証したかったけど…
なんかNuGet経由じゃないと
入手できなくなってる。
どうすりゃいいの?
16
3.C# (.NET系) から接続
実際にコードを書いて接続検証したかったけど…
NuGetパッケージマネージャコンソールから
次のコマンドを実行すれば入手できるらしい。
実際にコードを書いて接続検証したかったけど…
ダウンロード中に依存関係でエラーになった。
Visual Studio 2013を使ってるせい?
でも新しいVisual Studio入れてる暇ない。
PM> Install-Package Npgsql -Version 3.2.6
依存関係 'System.Threading.Tasks.Extensions (≥ 4.3.0)' の解決を試みています。
Install-Package : 'Npgsql' にはすでに 'System.Threading.Tasks.Extensions' に対して定義された
依存関係があります。
発生場所 行:1 文字:1
17
3.C# (.NET系) から接続
実際にコードを書いて接続検証したかったけど…
Stack Builder使えばライブラリを
普通にダウンロードできるよー
実際にコードを書いて接続検証したかったけど…
古いバージョン (3.0.8) しか入手できない。
やっぱり環境が古かったせい?
このバージョンをPMから入手できないかな?
できました
PM> Install-Package Npgsql -Version 3.0.8
'Npgsql 3.0.8' をインストールしています。
'Npgsql 3.0.8' が正常にインストールされました。
'Npgsql 3.0.8' を Sample_pos_conn_cs に追加しています。
'Npgsql 3.0.8' が Sample_pos_conn_cs に正常に追加されました。
18
3.C# (.NET系) から接続
ようやく実際にコードを書いて接続検証してみた。
●用意するもの
● PostgreSQL
● Visual Studio、Npgsql
● 大量の時間
 DBサーバ
● CentOS 7.3
● PostgreSQL 10.1
 クライアントサーバ
● Windows 10
● Visual Studio 2013
● .NET 4.5.1
● Npgsql 3.0.8
<検証環境>
19
3.C# (.NET系) から接続
実際に書いて接続してみた。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql;
using System.Data;
using System.Transactions;
namespace Sample_pos_conn_cs
{
class Class1
{
static void Main(String[] arge)
{
//接続文字列
string url = "Server=123.45.67.89;Port=5432;User ID=postgres;Password=password;Database=postgres;Enlist=true";
//PostgreSQLへ接続
using (NpgsqlConnection conn = new NpgsqlConnection(url))
using (TransactionScope tran = new TransactionScope())
{
conn.Open();
string sql = "INSERT INTO cs_test VALUES(1, 'AAA')";
NpgsqlCommand cmd1 = new NpgsqlCommand(sql, conn);
cmd1.ExecuteNonQuery();
//コミット
tran.Complete();
}
}
}
}
雰囲気を
感じてもらえれば・・・
20
3.C# (.NET系) から接続
実際に使う時の注意点的な何か。
●接続文字列
Server=DBサーバのIP or ホスト名;
Port=ポート番号;Database=DB名;
User ID=ユーザ名;Password=パスワード;
Enlist=true
Enlist = trueはTransactionScopeを使う場合に必要!
トランザクションをよろしくしてくれるスゴイやつ。
だけどNpgsqlだと調子悪い。
Npgsql 3.2から大幅に改善されたとか…。
21
3.C# (.NET系) から接続
実際に使う時の注意点的な何か。
●TransactionScope
using (TransactionScope tran = new TransactionScope())
{
…
}
TransactionScope内の処理を1トランザクションとして
扱ってくれる。分散トランザクションにも対応している。
ただし検証だと分散トランザクションに失敗する。
using (TransactionScope tran = new TransactionScope())
{
…
}
22
3.C# (.NET系) から接続
実際に使う時の注意点的な何か。
●TransactionScope
using (TransactionScope tran = new TransactionScope())
{
using (NpgsqlConnection conn1 = new NpgsqlConnection(url1))
…
using (NpgsqlConnection conn2 = new NpgsqlConnection(url2))
}
using (NpgsqlConnection conn1 = new NpgsqlConnection(url1))
using (NpgsqlConnection conn2 = new NpgsqlConnection(url2))
using (TransactionScope tran = new TransactionScope())
{
…
}
昔の検証で失敗したパターン
昔の検証で成功したパターン
23
4.おわりに
● RDBMSに依存しない接続コネクタ毎のクセがある。
● JDBCはトランザクションに注意。
● .NET系は環境構築がメンドイ。
● 他の言語からの接続は次の機会に…。
– 資料作る時間ありませんでした。
– 事前準備大事。
準備時間がなくなった原因の1つ→
https://qiita.com/mimitaro/items/7628c86ad8c69dfd3f03
Javaのソースコードはこちらから。C#もいずれ…。

色々な言語からPostgreSQLへ接続