Sqliteデータベースに対してデータアクセス層を実装しようとしています。私のテーブルの1つに日時フィールドが含まれています。
この日時フィールドにデータを挿入する際に問題が発生しました。
cmd.CommandText = string.Format(
"INSERT INTO Orders(" +
"OrderId, " +
"Status, " +
"CreationTime, " +
"LastModification, " +
"CreatorName) " +
"VALUES(@orderId,@status,@creation,@modification,@creator)";
cmd.Parameters.AddWithValue("@orderId", orderId);
cmd.Parameters.AddWithValue("@status", status);
cmd.Parameters.AddWithValue("@creation", creationTime);
cmd.Parameters.AddWithValue("@modification", lastModificationTime);
cmd.Parameters.AddWithValue("@creator", creatorName);
私のテーブルの作成:
cmd.CommandText = "CREATE TABLE IF NOT EXISTS Orders(" +
"OrderId TEXT PRIMARY KEY NOT NULL, " +
"Status TEXT, " +
"CreationTime DATETIME, " +
"LastModification DATETIME, " +
"CreatorName TEXT)";
手作業で文字列を作成する代わりに、パラメータ化されたクエリを使用してパラメータ値を追加します。String.Formatを使用すると、ご存知のとおり、間違いなく変換エラーが発生し、SQLインジェクション攻撃にさらされます。
パラメータを使用すると、値は変換なしで渡されるため、変換エラーやインジェクション攻撃について心配する必要はありません。また、ほとんどのデータベースは、どの部分が変更可能で、どの部分が実行ごとに同じままであるかを知っていると、クエリをより適切に最適化できます。
あなたの場合、あなたはこのようなものを使うことができます:
cmd.CommandText= "INSERT INTO Orders(" +
"OrderId, " +
"Status, " +
"CreationTime, " +
"LastModification, " +
"CreatorName) " +
"VALUES (@orderId,@status,@creation,@modification,@creator)";
cmd.Parameters.AddWithValue("@orderId",orderId);
cmd.Parameters.AddWithValue("@status",status);
cmd.Parameters.AddWithValue("@creation",creation);
cmd.Parameters.AddWithValue("@modification",modification);
cmd.Parameters.AddWithValue("@creator",creator);
トピック外-パラメータ化されたクエリが高速である理由
すべてのサーバーは、クエリを解析してその構造を理解し、クエリを実行するための実行プランを作成する必要があります。プランには、使用するインデックス、フィルタリングまたは結合の戦略、必要になる可能性のある一時的な構造などが含まれます。このプランの作成にはコストがかかるため、ほとんどのサーバーは、後で使用するために作成したプランをキャッシュします。
サーバーは、クエリ内のどの値が実際にパラメータであり、どの値が手動でコーディングされているかを認識していない限り、実際にクエリを解析せずに、既存のプランを使用できるか、新しいプランを作成できるかを判断できません。パラメータを自分で指定することにより、サーバーがはるかに優れた再利用可能なプランを作成できるようになります。毎秒多くのクエリを実行する場合、これは大幅な後押しになる可能性があります。
言うまでもなく、ネイティブ形式で値を渡す方がはるかに軽量であるため、テキストとして渡すよりも高速です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加