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 回答