【问题标题】:C# with SQL server syntax error带有 SQL 服务器语法错误的 C#
【发布时间】:2015-03-06 16:26:27
【问题描述】:

所以我已经看这个太久了,我可能错过了一些东西但我无法理解什么。尝试在标题为“单元号”的第三列中添加数据库条目时收到错误消息,错误指出尝试添加时该区域的语法无效。

SqlConnection cn = new SqlConnection(global::ProjectAssessment.Properties.Settings.Default.Database1ConnectionString);
        try
        {
            string sql = "INSERT INTO Students (Student_Id,Student_name,Unit_number,Unit_grade) values(" +textBox1.Text+ ",'" +textBox2.Text+ ",'" +textBox3.Text+ ",'" +textBox4.Text+"')";
            SqlCommand exesql = new SqlCommand(sql, cn);
            cn.Open();
            exesql.ExecuteNonQuery();

            MessageBox.Show("Student record added", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.studentsTableAdapter.Fill(this.database1DataSet.Students);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        finally
        {
            cn.Close();
        }

【问题讨论】:

    标签: c# sql database syntax


    【解决方案1】:
    string sql = "INSERT INTO Students (Student_Id,Student_name,Unit_number,Unit_grade) 
         values(" +textBox1.Text+ ",'" +textBox2.Text+ ",'" +textBox3.Text+ ",'" +textBox4.Text+"')";
    
                                                    //^^^^ and others
    

    一眼就能看出您的值中缺少单引号。您可以修复它们,但不要。使用SqlParameters,它们不仅可以使您免于此类错误,还可以使您免于 SQL 注入。

    所以你的代码应该是这样的:

    try
    {
        using (SqlConnection cn = new SqlConnection(global::ProjectAssessment.Properties.Settings.Default.Database1ConnectionString))
        using (SqlCommand exesql = new SqlCommand(@"INSERT INTO Students (Student_Id,Student_name,Unit_number,Unit_grade) values(@studentID, @studentName, @unitNumber, @unitGrade)", cn))
        {
            exesql.Parameters.Add("@studentID", SqlDbType.Int).Value = textBox1.Text;
            exesql.Parameters.Add("@studentName", SqlDbType.VarChar).Value = textBox2.Text;
            //... and others
    
            cn.Open();
            exesql.ExecuteNonQuery();
    
        }
    
        MessageBox.Show("Student record added", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
        this.studentsTableAdapter.Fill(this.database1DataSet.Students);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    

    using 语句中包含SqlConnectionSqlCommand 对象将确保资源的处置。 using 将转换为 try-finally 块,如果是 SqlConnection,它将关闭/释放连接。

    使用上面的代码,您不需要finally 块,因为连接将在using 语句的范围结束后被丢弃/关闭。

    【讨论】:

    • @Topher,欢迎您来到 Stack Overflow。
    • 复制/粘贴错误:finally 中的 cn 对象现在超出范围...所以不需要 finally。
    • @ShellShock,感谢您指出。修改了答案。
    【解决方案2】:
    string sql = "INSERT INTO Students (Student_Id,Student_name,Unit_number,Unit_grade) values(" +textBox1.Text+ ",'" +textBox2.Text+ ",'" +textBox3.Text+ ",'" +textBox4.Text+"')";
    

    应该是

    string sql = "INSERT INTO Students (Student_Id,Student_name,Unit_number,Unit_grade) values(" +textBox1.Text+ ",'" +textBox2.Text+ "','" +textBox3.Text+ "','" +textBox4.Text+"')";
    

    请注意,这是非常不安全的,并且容易发生 SQL 注入!例如,如果有人决定学生 ID 应该是 ;DROP TABLE STUDENTS; --,那么您的 SQL 语句将如下所示:

    INSERT INTO STUDENTS (Student_Id, Student_name, Unit_number, Unit_grade) values(;DROP TABLE STUDENTS; --, 'tb2val', 'tb3val', 'tb4val')
    

    根据执行的方式,第一个语句会抛出语法错误,第二个语句 (DROP TABLE STUDENTS;) 会删除您的表,其余的将被视为 cmets。

    哎呀,你的学生桌到了!

    您应该使用 Habib 的 C# 代码来避免这个问题。

    【讨论】:

    • 感谢您的建议,我实际上并不知道我会把它留在那里注射,所以我很感激这个提示 :)
    猜你喜欢
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多