2013-06-15 21 views
5

基本的には、ボタンをクリックすると、ユーザーは選択した内容に従って特定の行からデータを抽出し、INSERTを使用して別のテーブルに配置します。以下はコードです。SQL Insertステートメントの構文

private void button3_Click(object sender, EventArgs e) 
{ 
     const String connectionString = "Data Source = Vanessa-PC\\SQLEXPRESS; Initial Catalog = IUMDC; Connect Timeout = 15; Integrated Security = true"; 
     SqlConnection con = new SqlConnection(connectionString); 

     //int SituationID1; 
     label24.Show(); 

     foreach (SitID x in Sittbl) 
     { 
      if (x.ID == Convert.ToInt16(comboBox1.SelectedItem)) 
      { 
       try 
       { 
        con.Open(); 
        SqlCommand command = new SqlCommand("SELECT * FROM Situation WHERE SituationID=" + x.SitIDs, con); 
        SqlDataReader dr = command.ExecuteReader(); 

        while (dr.Read()) 
        { 
         sitid1 = Convert.ToInt32(dr[0]); 
         name1 = dr[4].ToString(); 
         incident1 = Convert.ToDateTime(dr[1]); 
         charges1 = dr[5].ToString(); 
         nature1 = dr[2].ToString(); 
        } 

        con.Close(); 
       } 
       catch (SqlException ex) 
       { 
        MessageBox.Show("Database failed to connect" + ex.Message); 
       } 

       //SituationID = x.SitIDs; 
      } 
     } 

     try 
     {      
      con.Open(); 
      SqlCommand command1 = new SqlCommand("INSERT INTO CurrentSit VALUES (" + sitid1 + ",'" + incident1.ToString("YYYY-mm-DD") + "', '" + nature1 + "', '" + name1 + "', '" + charges1 + "'", con); 
      SqlDataReader dr1 = command1.ExecuteReader(); 
      con.Close(); 
     } 
     catch (SqlException ex) 
     { 
      MessageBox.Show("Database failed to connect" + ex.Message); 
     } 
     //Situation Sit = new Situation(); 
     //Sit.ShowDialog(); 
    } 

私のコードは2つのテーブルの種類が同じであると私は徹底的にこれをテストしようとしてい

行項目の近くに不適切な構文を」失敗して言います!

+0

'INSERT'を行うとき、あなたはデータの収集を返していない - ので、あなたは' command1.ExecuteNonQueryを(使用する必要があります); 'の代わりに、 '.ExecuteReader()'ここで読者を無視すると、本当に.... –

答えて

15

が見えます。たぶん理由は、あなたのSQLステートメントでアポストロフィの使用ですが、あなたはそれに気を付けるべきではありません。なぜ私はあなたが気にしてはならないのか、私の答えの真ん中で説明します。

SqlCommand command1 = new SqlCommand("INSERT INTO CurrentSit VALUES (" + sitid1 + ",'" + incident1.ToString("YYYY-mm-DD") + "', '" + nature1 + "', '" + name1 + "', '" + charges1 + "'", con); 

正確に何が問題なのかを調べるには、代わりに列名を指定します。しかし、パラメータ化クエリを使用して列名を指定する必要はありません。

SqlCommand command1 = new SqlCommand("INSERT INTO CurrentSit VALUES(@sitid1, @incident1, @nature1, @name1, @charges1)", con); 

command1.Parameters.AddWithValue("@sitid1", sitid1); 
command1.Parameters.AddWithValue("@incident1", incident1.ToString("YYYY-mm-DD")); 
command1.Parameters.AddWithValue("@nature1", nature1); 
command1.Parameters.AddWithValue("@name1", name1); 
command1.Parameters.AddWithValue("@charges1", charges1); 

command1.ExecuteNonQuery(); 

あなたはいつもparameterized queriesを使用する必要があります。この種のコードはSQL Injectionの攻撃に対して公開されています。

Marc mentionedと同様に、このSQL文ではExecuteReader()を使用する必要はありません。このデータはINSERTのデータであり、データは返されないためです。そのため、この場合はExecuteNonQuery()を使用する必要があります。

+1

あなたは今私がいかに感謝しているか分かりません!どうもありがとうございます! – NetUser101

4

は、クエリの列を指定してください:追加の注意点としては

"INSERT INTO CurrentSit (sitid, incident, nature, name1, charges) VALUES (" + sitid1 + ",'" + incident1.ToString("YYYY-mm-DD") + "', '" + nature1 + "', '" + name1 + "', '" + charges1 + "'", con)"; 

、またparamerterizedクエリを使用することを学びます。例えば:あなたの最後のSQL文が正しくないよう

command1.Parameters.AddWithValue("@name1", name1); 
command1.Parameters.AddWithValue("@charges1", charges1); 

http://johnhforrest.com/2010/10/parameterized-sql-queries-in-c/

3

すぐに問題が発生するのは、INSERTステートメントに無効な構文が含まれていることです。あなたがそれを構築するために使用している値のうちの1つは、あなたの文字列を早期に終了させるアポストロフィを持っています。

は決してこのようにinsert文を作成しないでください。あなたが見ている種類のエラーに高い傾向があることに加えて、SQLインジェクション攻撃に対する古典的な開放点でもあります。 (たとえば、状況の性質がfoo'); drop table situation; --の場合を想像してください)。

あなたはパラメータ化クエリを使用する必要があります。

var sql = "INSERT INTO CurrentSit VALUES (@sitid, @incident, @nature, @name, @charges)" 
var cmd = new SqlCommand(sql, con); 
cmd.Parameters.Add("@Sitid", SqlDbType.Int).Value = sitid1; 
// etc.