INSERT ... SELECT 構文を使用して、テーブルから既存の行を選択し、別のテーブルに挿入しています。各行の既存のデータに加えて、BillingID と TimeStamp も追加する必要があります。これらのフィールドは SQL ステートメントの SELECT 部分にあるため、パラメーター化できません。SQL 関数 NOW() を使用して TimeStamp の問題を解決しましたが、次のように文字列連結を介してクエリに追加した BillingID が残っています。
static void UpdateMonthlyData(int BillingID, DateTime HistoryDate, int CompanyID)
{
String conString = ConfigurationManager.ConnectionStrings["xxx"].ConnectionString;
MySqlConnection connection = new MySqlConnection(conString);
String command = "INSERT INTO MonthlyData SELECT " + BillingID + ", d.*, NOW() "
+ "FROM CurrentData d WHERE d.CompanyID = @CompanyID AND d.HistoryDate = @HistoryDate";
MySqlCommand cmd = new MySqlCommand(command, connection);
cmd.Parameters.Add(new MySqlParameter("@CompanyID", CompanyID));
cmd.Parameters.Add(new MySqlParameter("@HistoryDate", HistoryDate));
cmd.CommandType = CommandType.Text;
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
SQL インジェクションは自動化されたスケジュールで実行されるコンソール アプリであり、ユーザーの操作はまったくないため、私は心配していません。(BillingID は自動生成されます)。それにもかかわらず、連結された文字列はあまり読みにくいため、使用するのは好きではありません。これを行うよりエレガントな方法はありますか?
編集:
要約すると、これができないので、次のように考えました。
SELECT @field FROM @table
SQL ステートメントの SELECT 部分ではパラメーターを使用できないと思いました。ただし、列を選択するのではなく、select ステートメントで値を指定しているため、@cdhowie が指摘したように、そこでパラメーターを使用できます。本質的に、翻訳された私のクエリは次のようなものです:
SELECT 25 FROM table_name, not SELECT field FROM table_name
だから今@cdhowieのおかげで、パラメータはリテラル値がどこにでもあることができることを理解しています