更新処理

  1. Dapperによる更新処理はExecute()メソッドを使いUPDATEのSQLを実行し、影響を受けた行数を返します。
  2. WHERE句は必須です。記述しないとテーブル内の全レコードが更新されてしまいます!
  3. 非推奨:文字列連結でSQLを作成する方法(図の素朴な実装)。SQLインジェクションの脆弱性が発生します。
  4. 推奨:パラメータ化クエリ。@パラメータ名を使用し、エンティティまたは匿名クラスから自動的にパラメータをマッピングします。

元の説明:更新の考え方は挿入処理と似ています。UPDATE文を記述し、WHERE句で対象行だけを更新するよう制限します。

サンプルコード

// 危険なコード!文字列連結によりSQLインジェクションが発生、悪い例として掲載
using (IDbConnection db = new MySqlConnection(conn))
{
    var id = 1;
    string sqlUpdate = "UPDATE student set FirstName='新しい名前',LastName='新しい姓',Email='新しいメール' WHERE Id=" + id;
    int rows = db.Execute(sqlUpdate);
    var info = db.Query<Student>("Select * From student WHERE Id=" + id, new { id }).SingleOrDefault();
}Code language: C# (cs)

標準的なパラメータ化記述

using System.Data;
using MySql.Data.MySqlClient;
using Dapper;
using System.Configuration;

static void Main(string[] args)
{
    var conn = ConfigurationManager.ConnectionStrings["StudentConnection"].ConnectionString;
    using (IDbConnection db = new MySqlConnection(conn))
    {
        // 1.更新用SQL、@パラメータプレースホルダーを使用
        string sqlUpdate = @"UPDATE student 
                             SET FirstName=@FirstName, LastName=@LastName, Email=@Email 
                             WHERE Id=@Id";

        // 2.更新データをエンティティオブジェクトで用意
        var stu = new Student()
        {
            Id = 1,
            FirstName = "foxdevelop",
            LastName = "com",
            Email = "admin@foxdevelop.com"
        };

        // 3.更新実行、影響行数を取得
        int rowsAffected = db.Execute(sqlUpdate, stu);

        // 4.クエリで更新結果を確認
        var studentInfo = db.Query<Student>(
            "SELECT * FROM student WHERE Id=@Id",
            new { Id = 1 }
        ).SingleOrDefault();
    }
    Console.ReadKey();
}

// Studentエンティティクラス
public class Student
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}Code language: C# (cs)
  1. WHERE句は絶対に必要
    WHEREを忘れるとUPDATE student SET xxxとなり、テーブル全行が書き換わり重大な障害となります。
  2. パラメータ名の一致
    SQL内の@パラメータ名とエンティティ・匿名クラスのプロパティは大文字小文字を区別しませんが、名前自体は同一にしてください。
  3. 戻り値の意味
    int rowsAffected:0より大きければ該当行更新成功、0の場合は条件に合致するレコードが存在しません。
  4. セキュリティ注意点
    文字列連結でSQLを組み立ててはいけません。外部からの入力によりSQLインジェクションが引き起こされます。

一部フィールドだけ更新する

メールアドレスだけ変更したい場合、全カラムを記述する必要はありません:

UPDATE student SET Email=@Email WHERE Id=@Id

更新処理

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です