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

2021/10/14

C# Npgsql

アイキャッチ

今回はNpgsqlDataAdapterを使ったDELETEの解説です。

正直あまり解説する内容は多くなく、特筆する点もありませんが基本的に使う手段の1つでもありますので解説したいと思います。

Npgsqlの本家情報は

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

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

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

時間はCREATE TABLEで「time timestamp DEFAULT clock_timestamp()」としており、意図的に時間をセットできますが、何もINSERTしなければ自動的に現在の時間がセットされます。

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

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

DELETEのきほん

オーソドックスな手法から

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);
// データを削除
dt.Rows[0].Delete();
// データベースにDELETEするNpgsqlCommandを追加
using NpgsqlCommand deleteCommand = new();
deleteCommand.Connection = con;
deleteCommand.CommandText = "DELETE FROM data WHERE id = @id";
// 「id」を条件としてDELETEするNpgsqlParameterを作成して追加
NpgsqlParameter deleteId = new();
deleteId.ParameterName = "@id";
deleteId.SourceColumn = "id";
_ = deleteCommand.Parameters.Add(deleteId);
// NpgsqlDataAdapterのInsertCommandに追加
nda.DeleteCommand = deleteCommand;
try
{
    result = nda.Update(dt);
}
catch (DBConcurrencyException)
{
    // INSERT、UPDATE、DELETE の各ステートメントを実行しようとしましたが、影響を受けたレコードがない
}

まずはFillメソッドで全てのデータを取得します。

その後DataTableの先頭の行を削除します。

これでデータの編集は完了です。

    DELETEの手順としては
  1. DELETEするデータ用NpgsqlCommandを作る。
  2. DELETEするデータのクエリ文に渡すパワメータの数だけNpgsqlParameterを作る。
  3. NpgsqlParameteのParameterNameとSourceColumnを適切に設定する。
  4. NpgsqlCommandのParameters.Addメソッドを実行し作ったNpgsqlParameteを渡す。
  5. NpgsqlDataAdapterのDeleteCommandプロパティへNpgsqlCommandを渡す。
  6. NpgsqlDataAdapteのUpdateメソッドを実行する。

手順は前回解説したUPDATEとほぼ同じでクエリ文とNpgsqlDataAdapterのDeleteCommandプロパティへNpgsqlCommandを渡すのが違うだけです。

手順1がサンプルコードの9~11行目に該当します。

11行目で実際に実行するクエリ文と渡す値のパラメータをセットします。

手順,2,3,4はサンプルコード13~15行目が該当します。

NpgsqlParameterのParameterNameにはクエリ文で指定したパラメータ(@○○○)、SourceColumnにはデータベーステーブルの(またはDataTable)のカラム名を指定します。

そして手順5は18行目となります。

実際のDELETE実行は21行目ですが、正常にDELETEできなかった時のために例外「DBConcurrencyException」をキャッチできるようにすれば完璧です。

NpgsqlCommandBuilderを使ったDELETE

INSERTやUPDATEで紹介した手法とほぼ一緒と言ってもいいでしょう。

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);
// データを削除
dt.Rows[0].Delete();
using NpgsqlCommandBuilder cb = new(nda);
try
{
    result = nda.Update(dt);
}
catch (DBConcurrencyException)
{
    // INSERT、UPDATE、DELETE の各ステートメントを実行しようとしましたが、影響を受けたレコードがない
}

取得したデータが入っているDataTableのデータを1行削除しNpgsqlCommandBuilderを利用してデーテベースに反映させます。

ちなみにNpgsqlCommandBuilderのGetDeleteCommand().CommandTextプロパティを見ると

DELETE FROM "db_PostgreTest"."public"."data" WHERE (("id" = @p1) AND ((@p2 = 1 AND "time" IS NULL) OR ("time" = @p3)) AND ((@p4 = 1 AND "name" IS NULL) OR ("name" = @p5)) AND ((@p6 = 1 AND "numeric" IS NULL) OR ("numeric" = @p7)))

となっており、前回のUPDATE同様、全ての条件が一致したデータを削除しますので、既に誰かが削除したとかUPDATEされた場合は条件に一致するデータはありませんので例外となります。

自己紹介

自分の写真



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

カテゴリ

このブログを検索

QooQ