4

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のおかげで、パラメータはリテラル値がどこにでもあることができることを理解しています

4

3 に答える 3

3

クエリ パラメータは、クエリ パラメータが正しい型であると仮定して、リテラル値が存在する場所ならどこでも有効です (たとえば... LIMIT @Foo、整数をバインドしている限り、または SQL サーバーが整数に正常に変換できるものであれば動作するはずです)。 Foo パラメータ)。もちろん、これは、使用している SQL ダイアレクトに特定の癖がないことを前提としています。

BillingIDつまり、クエリ パラメーターを使用して渡すことができないという理由はありません。

于 2013-04-22T21:56:22.673 に答える