0

C# で Windows フォーム アプリケーションを使用して SQL Server 2008 R2 データベースにデータを保存すると問題が発生します。保存ボタンのコードは正しいのですが、このボタンをクリックするとメッセージボックスが表示されます

無効な列名「CompanyID」...およびその他の列

ただし、列はデータベース テーブルに存在します。

私のコードは

SqlConnection con = new SqlConnection(GetConnection.ConnectionStr);
string sqltext = "insert into MVConsumingMaker ( [CompanyID] , [MakerID] , [Hour] , [Amount] , [Date] ) values(" + Convert.ToString(CmpCompany.ValueMember) + "," + Convert.ToString(CmpMaker.ValueMember) + "," + CmpHour.Text + "," + TxtAmount.Text + ",'" + MaskDate.Text + "')";
SqlCommand cmd = new SqlCommand(sqltext, con);

con.Open();

cmd.ExecuteNonQuery();
con.Close();

TxtResultSave.Text = "the opiration was completed successfully";

私が間違っていることを教えてください!

ありがとうございました..

4

1 に答える 1

0

さて、あなたの最初の大きな問題は、SQL ステートメントを作成するために文字列連結を使用しているという事実です。コードをSQL インジェクションに対して開いているため、これは本当に悪いことです。絶対にしないでください. この問題を解決する唯一の適切な方法は、常にパラメーター化されたクエリを使用することです。SQLステートメントを定義し、値を「挿入」したい場合は常に、コードから適切かつ安全に値を設定できるようにします。@parameter

また、パラメーターを使用すると、SQL ステートメントで適切な数の引用符や二重引用符を使用するなどの厄介な問題に対処する必要がなくなります。パラメーターにはデータ型が割り当てられるため、より多くのエラー制御が可能になります。設定しようとすると、適切なエラー メッセージが表示されます。

また、データ アクセス ロジックを UI ロジックから分離するようにしてください。UI イベント ハンドラの途中ですべてのデータベース コードを記述しないでください。それらを分離する - はるかに優れたクリーンな設計により、コードを再利用でき、コード ベースの全体的な保守性が向上します。

したがって、次のようなメソッドを記述します。

public void SaveData(int companyID, int makerID, int hour, decimal amount, DateTime date)
{
    // define your SQL statement using *parameters*
    string sqltext = "INSERT INTO dbo.MVConsumingMaker([CompanyID], [MakerID], [Hour], [Amount], [Date]) " +
                     "VALUES(@CompanyID, @MakerID, @Hour, @Amount, @Date)";

    // put your disposable ADO.NET objects into "using" blocks to ensure proper disposal
    using (SqlConnection con = new SqlConnection(GetConnection.ConnectionStr))
    using (SqlCommand cmd = new SqlCommand(sqltext, con))
    {
        // define parameters and their values
        cmd.Parameters.Add("@CompanyID", SqlDbType.Int).Value = companyID;
        cmd.Parameters.Add("@MakerID", SqlDbType.Int).Value = makerID;
        cmd.Parameters.Add("@Hour", SqlDbType.Int).Value = hour;
        cmd.Parameters.Add("@Amount", SqlDbType.Decimal).Value = amount;
        cmd.Parameters.Add("@Date", SqlDbType.DateTime).Value = date;

        // open connection, execute INSERT, close connection
        con.Open();
        cmd.ExecuteNonQuery();
        con.Close();
    }
}

次に、イベント ハンドラーにそのメソッドを呼び出させます。

try
{
    // call the "SaveData" method to actually save the data from the UI elements
    SaveData(Convert.ToString(CmpCompany.ValueMember), 
             Convert.ToString(CmpMaker.ValueMember), 
             CmpHour.Text, TxtAmount.Text, MaskDate.Text);

    // set result text here - in the UI event handler
    TxtResultSave.Text = "The data was successfully saved!";
}
catch(Exception exc)
{
   // handle and/or log exception as needed
   TxtResultSave.Text = "The data was *NOT* successfully saved";
}
于 2012-04-12T20:38:03.850 に答える