C#でNpgsqlを使ってPostgreSQLへアクセス【NpgsqlDataAdapterでSELECT】

2021/10/01

C# Npgsql

アイキャッチ

今まではクエリ文を実行後、データを1個ずつ取得していましたがNpgsqlDataAdapterとDataTableを利用し、まとめてデータを取得する方法の解説です。

速度的には遅いんじゃ?と予想される方も多いかと思います。

私も遅いと予想していますが、今時なPCで耐えれれる遅さなのかはわかりませんので、NpgsqlDataAdapterに関する一通りの解説が終わったら実験してみようかと思います。(今回の記事では行いません)

Npgsqlの本家情報は

私の作成するサンプルソースファイルは

基本的なテーブルは下記構成となります。

テーブル名 概要
id serial 自動的にセットされる通し番号
time timestamp トランザクション開始時刻または入力された日付
name text 任意の文字列
numeric integer 任意の数値

このテーブルに下記2つのデータが存在しているのを前提として説明します。

id time name numeric
1 INSERTした時間 a 1
2 INSERTした時間 b 2

SELECTのきほん

まずは一番オーソドックスな全部のデータを取得してみます。

using DataTable dt = new();
using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
con.Open();
using NpgsqlDataAdapter nda = new("SELECT * FROM data;", con);
var result = nda.Fill(dt);
Console.WriteLine($"{dt.Columns[0].ColumnName} {dt.Columns[1].ColumnName} {dt.Columns[2].ColumnName} {dt.Columns[3].ColumnName}");
for (int i = 0; i < dt.Rows.Count; i++)
{
    Console.WriteLine($"{dt.Rows[i][0]} {dt.Rows[i][1]} {dt.Rows[i][2]} {dt.Rows[i][3]}");
}

まずはNpgsqlConnectionで接続しNpgsqlDataAdapterにSELECT文とNpgsqlConnectionインスタンスを渡します。

NpgsqlDataAdapterには4種類の引数パターンがありますが、うち3つはSELECTに関する引数です。

まずはSELECTしないと始まらないからでしょう。

データを取得する準備ができたらNpgsqlDataAdapterのFillメソッドでデータを取得します。

今回はDataTableを引数としていますが、DataSetを引数にもできますので用途に応じて変えてください。

上記プログラムを実行するとコンソールボックスには

id,time,name,numeric

1,2021/10/01 6:46:16,a,1

2,2021/10/01 6:46:16,b,2

と表示され、全てのカラム名とデータが取得できます。

尚、NpgsqlDataAdapterには2つ目の引数に接続文字列を入れNpgsqlConnectionを省略する事も可能です。

// 2つ目の引数が接続文字列
using NpgsqlDataAdapter nda = new("SELECT * FROM data;", "Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");

接続に関する2行省略できますので以降の記述次第ではこちらがいいかもしれません。

取得するデータを絞る

クエリ文の基礎みたいな話になってしまいますが、「SELECT name」と取得するデータを指定した場合の確認もやってみます。

using DataTable dt = new();
using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
con.Open();
using NpgsqlDataAdapter nda = new("SELECT name FROM data;", con);
var result = nda.Fill(dt);
// 取得可能なカラム数は「dt.Columns.Count」で取得可能
Console.WriteLine($"{dt.Columns[0].ColumnName}");
for (int i = 0; i < dt.Rows.Count; i++)
{
    Console.WriteLine($"{dt.Rows[i][0]}");
}

カラム名nameだけを取得してみました。

name

a

b

コンソールボックスには上記3行が表示されます。

SELECTで取得するデータを絞るとDataTableの要素番号が変わるので注意してください。

取得するデータの条件を指定

これもまたクエリ文の基礎みたいな話ですが、正しくデータが取得できるかの再確認をしてみます。

using DataTable dt = new();
using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
con.Open();
using NpgsqlDataAdapter nda = new("SELECT * FROM data WHERE name = 'a';", con);
var result = nda.Fill(dt);
Console.WriteLine($"{dt.Columns[0].ColumnName},{dt.Columns[1].ColumnName},{dt.Columns[2].ColumnName},{dt.Columns[3].ColumnName}");
for (int i = 0; i < dt.Rows.Count; i++)
{
    Console.WriteLine($"{dt.Rows[i][0]},{dt.Rows[i][1]},{dt.Rows[i][2]},{dt.Rows[i][3]}");
}

条件としてnameがaのデータだけを取得してみました。

id,time,name,numeric

1,2021/10/01 6:46:16,a,1

無事nameがaのデータだけが読み込めました。

いままで解説した手法よりは記述が短くなり、取得したデータの扱いも簡単なのでDataTableを使い慣れた方にはアリな手法かと思います。

自己紹介

自分の写真



新潟県のとある企業で働いてます。
【できる事】
電子回路設計
基板パターン設計
マイコンプログラム
C#(WinForms WPF)を使ったWindowsアプリケーション作成
PLCラダー
自動化装置アドバイザー
にほんブログ村 IT技術ブログ ソフトウェアへ

カテゴリ

このブログを検索

QooQ