web-dev-qa-db-ja.com

oledbを使用してアクセステーブルにレコードを挿入するにはどうすればよいですか?

MS Accessにこのアイテムテーブルがあります

Items(Table)    
Item_Id(autonumber)
Item_Name(text)
Item_Price(currency)

このコードを使用してレコードを挿入しようとしています。

OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["DbConn"].ToString());
        OleDbCommand cmd = new OleDbCommand();
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "insert into Items ([Item_Name],[Item_Price]) values ('" + itemNameTBox.Text + "','" + Convert.ToDouble(itemPriceTBox.Text) + "')";
        cmd.Connection = myCon;
        myCon.Open();
        cmd.ExecuteNonQuery();
        System.Windows.Forms.MessageBox.Show("An Item has been successfully added", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
        myCon.Close();

コードはエラーなしで実行されていますが、最後にテーブルにレコードが見つかりません。

9
mepk

SQL挿入テキストはパラメーターを使用しません。
これはバグの原因であり、さらに悪いことになります (SqlInjection)

この方法でコードを変更します。

using(OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["DbConn"].ToString()))
{
   OleDbCommand cmd = new OleDbCommand(); 
   cmd.CommandType = CommandType.Text; 
   cmd.CommandText = "insert into Items ([Item_Name],[Item_Price]) values (?,?);
   cmd.Parameters.AddWithValue("@item", itemNameTBox.Text);
   cmd.Parameters.AddWithValue("@price", Convert.ToDouble(itemPriceTBox.Text)); 
   cmd.Connection = myCon; 
   myCon.Open(); 
   cmd.ExecuteNonQuery(); 
   System.Windows.Forms.MessageBox.Show("An Item has been successfully added", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Information); 
}

もちろん、これは価格のテキストボックスに正しい数値が含まれていることを前提としています。
上記のコードを呼び出す前に必ずこの行を追加してください

double price;
if(double.TryParse(itemPriceTBox.Text, out price) == false)
{
    MessageBox.Show("Invalid price");
    return;
}

次に、パラメータ@priceの値としてpriceを使用します

** 4年後に編集**

この回答は更新が必要です。上記のコードでは、AddWithValueを使用してParametersコレクションにパラメーターを追加しています。それは機能しますが、AddWithValueにはいくつかの欠点があることをすべての読者に通知する必要があります。特に、宛先列が10進値または日付を予期しているときに、文字列だけを追加する簡単なパスに当てはまる場合。この文脈で私が

cmd.Parameters.AddWithValue("@price", itemPriceTBox.Text); 

その結果、構文エラーまたは値のある種の奇妙な変換が発生する可能性があり、同じことが日付でも発生する可能性があります。 AddWithValueは文字列パラメータを作成し、データベースエンジンは値を予期される列タイプに変換する必要があります。ただし、クライアントとサーバーのロケールの違いにより、値のあらゆる種類の誤解が生じる可能性があります。

いつも使うほうがいいと思います

cmd.Parameters.Add("@price", OleDbType.Decimal).Value = 
           Convert.ToDecimal(itemPriceTBox.Text); 

AddWithValueの問題の詳細については、こちらをご覧ください

13
Steve