这个简单的更新查询有什么问题?

Kyl*_*and 2 c# sql sql-server asp.net

除了不安全...我没有收到任何错误消息,但行没有更新.行整数在查询后设置为1,表示1行受到影响.

String query = "UPDATE contacts SET contact_name = '" + ContactName.Text.Trim() + "', " +
            "contact_phone = '" + Phone.Text.Trim() + "', " +
            "contact_fax = '" + Fax.Text.Trim() + "', " +
            "contact_direct = '" + Direct.Text.Trim() + "', " +
            "company_id = '" + Company.SelectedValue + "', " +
            "contact_address1 = '" + Address1.Text.Trim() + "', " +
            "contact_address2 = '" + Address2.Text.Trim() + "', " +
            "contact_city = '" + City.Text.Trim() + "', " +
            "contact_state = '" + State.SelectedValue + "', " +
            "contact_zip = '" + Zip.Text.Trim() + "' " + 
            "WHERE contact_id = '" + contact_id + "'";

String cs = Lib.GetConnectionString(null);
SqlConnection conn = new SqlConnection(cs);

SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = query;
cmd.Connection.Open();
int rows = cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)

Sky*_*ers 9

您应该使用参数化查询有以下几个原因:

  • 消除嵌入式违反查询的可能性
  • 保护您的数据库/网站免受SQL注入

此外,如果cmd返回1,则更新行.您可能需要检查您的期望......

String query = @"
    UPDATE contacts 
    SET contact_name = @contact_name, contact_phone = @contact_phone, contact_fax = @contact_fax, 
        contact_direct = @contact_direct , company_id = @company_id, contact_address1 = @contact_address1, 
        contact_address2 =@contact_address2, contact_city = @contact_city , contact_state = @contact_state,  
        contact_zip = @contact_zip 
    WHERE contact_id = @contact_id";

String cs = Lib.GetConnectionString(null);
using (SqlConnection conn = new SqlConnection(cs))
{
    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.Parameters.AddWithValue("@contact_name", ContactName.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_phone", Phone.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_fax", Fax.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_direct", Direct.Text.Trim());
        cmd.Parameters.AddWithValue("@company_id", Company.SelectedValue);
        cmd.Parameters.AddWithValue("@contact_address1", Address1.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_address2", Address2.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_city", City.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_state", State.SelectedValue);
        cmd.Parameters.AddWithValue("@contact_zip", Zip.Text.Trim());
        cmd.Parameters.AddWithValue("@contact_id", contact_id);
        cmd.CommandText = query;
        cmd.Connection.Open();
        int rows = cmd.ExecuteNonQuery();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,这看起来不那么干净吗?当你明白为什么时,它会给你一种温暖的模糊感觉,让你在晚上睡个好觉.;-)

澄清:

您声明的问题是"此查询有什么问题".答案是什么.查询没有错.

问题在于您的页面代码,即使在5个人提示查询没有任何问题之后您也没有发布.

我的意思是'你可能需要检查你的期望......'和'你需要在执行查询之前检查参数中的数据,以确保它们是你想要的',John更清楚地描述了,但是让我简要地再说一遍:

显示的查询表面上是正确的,应该按预期执行.您可能遇到的是周围代码逻辑的缺陷.

您很可能在没有IsPostback保护的情况下在page_load中进行数据绑定,从而用原始数据覆盖输入值.

只需在第一次加载时,您需要加载和绑定控件/页面一次.此后,控件的状态将保存在viewstate中,该视图状态存储在html的隐藏字段中.如果您只是在每个页面加载时绑定到数据源,您将覆盖任何输入

所以让我们来看看它的工作原理

这是一个合适的逻辑流程

protected void Page_Load(object sender, EventArgs e)
{
    System.Diagnostics.Trace.WriteLine("Page_Load");
    if (!IsPostBack)
    {
        System.Diagnostics.Trace.WriteLine("\tBind TextBox1");
        TextBox1.Text = "Initial Value";
    }
    System.Diagnostics.Trace.WriteLine("\tTextBox1.Text = " + TextBox1.Text);
}

protected void Button1_Click(object sender, EventArgs e)
{
    System.Diagnostics.Trace.WriteLine("Button1_Click");
    System.Diagnostics.Trace.WriteLine("\tTextBox1.Text = " + TextBox1.Text);
}
Run Code Online (Sandbox Code Playgroud)

如果您加载此页面,请在文本框中输入"新值",然后单击按钮1,这是Trace显示的内容:

    Page_Load
        Bind TextBox1
        TextBox1.Text = Initial Value

    Page_Load
        TextBox1.Text = New Value

    Button1_Click
        TextBox1.Text = New Value

但没有警卫:

protected void Page_Load(object sender, EventArgs e)
{
    System.Diagnostics.Trace.WriteLine("Page_Load");
    System.Diagnostics.Trace.WriteLine("\tBind TextBox1");
    TextBox1.Text = "Initial Value";
    System.Diagnostics.Trace.WriteLine("\tTextBox1.Text = " + TextBox1.Text);
}

        protected void Button1_Click(object sender, EventArgs e)
{
    System.Diagnostics.Trace.WriteLine("Button1_Click");
    System.Diagnostics.Trace.WriteLine("\tTextBox1.Text = " + TextBox1.Text);
}
Run Code Online (Sandbox Code Playgroud)

你得到了你可能遇到的结果......

    Page_Load
        Bind TextBox1
        TextBox1.Text = Initial Value

    Page_Load
        Bind TextBox1
        TextBox1.Text = Initial Value

    Button1_Click
        TextBox1.Text = Initial Value

但同样,一个可以帮助您的实用调试技术是在执行查询之前中断更新方法并检查值以验证它们是您认为它们是什么然后从那里开始.