なべひろBlog

プログラミングをメインに仕事に関するアレコレを発信しています。

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

今まではクエリ文を実行後、データを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 adp = new("SELECT * FROM data;", con);
var result = adp.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 adp = 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 adp = new("SELECT name FROM data;", con);
var result = adp.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 adp = new("SELECT * FROM data WHERE name = 'a';", con);
var result = adp.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を使い慣れた方にはアリな手法かと思います。
関連記事