【问题标题】:Getting odd error on .net ExecuteNonQuery在.net ExecuteNonQuery 上出现奇怪的错误
【发布时间】:2009-01-20 19:43:23
【问题描述】:

我在 .NET 中使用后端的 SQL Server 工作

我有一个数据库,我使用 Web 控件创建了一条记录 - 然后我需要更新一些字段。
我可以捕获 sql 语句并在 sql server 中成功运行它 - 但是,当我尝试运行执行非查询时,我收到以下错误:

未处理的执行错误 '

这是我的功能:

Public Function UpdateTicketValues(ByVal srId As String) As Boolean
    Dim result As Boolean
    Dim myCDataReader As System.Data.SqlClient.SqlDataReader
    Dim myUConn As New System.Data.SqlClient.SqlConnection
    Dim myCCmd As New System.Data.SqlClient.SqlCommand
    Dim myUCmd As New System.Data.SqlClient.SqlCommand
    Dim strSQL As String

    strSQL = "SELECT Contact_RecId, First_Name, Last_Name, PhoneNbr, Extension, Email FROM vti_ContactInformation " & _
             "WHERE Company_RecId = " & CoId & " AND Email = '" & txtEmail.Text & "'"
    myCConn.Open()
    myUConn = New System.Data.SqlClient.SqlConnection("Data Source=x;Initial Catalog=x;User Id=x;Password=x;Trusted_Connection=False")
    myUConn.Open()
    myCCmd.Connection = myCConn
    myCCmd.CommandText = strSQL
    myCDataReader = myCCmd.ExecuteReader
    If myCDataReader.Read() Then
        'Run update with contact information
        strSQL = "UPDATE SR_Service " & _
                 "SET Contact_RecId = " & myCDataReader.GetValue(0) & ", " & _
                 "    Contact_Name = '" & myCDataReader.GetValue(1) & " " & myCDataReader.GetValue(2) & "', " & _
                 "    PhoneNbr = '" & myCDataReader.GetValue(3) & "', " & _
                 "    Extension = '" & myCDataReader.GetValue(4) & "', " & _
                 "    Email_Address = '" & myCDataReader.GetValue(5) & "' " & _
                 "WHERE SR_Service_RecId = " & srId & " "
        myUCmd.Connection = myUConn
        myUCmd.CommandText = strSQL
        'myCCmd.ExecuteNonQuery()
        lblServiceRequest.Text = myUCmd.CommandText
        result = True
    Else
        myUCmd.CommandText = ""
        result = False
    End If
    If myUCmd.CommandText <> "" Then
        myUCmd.ExecuteNonQuery()
    End If
    myCConn.Close()
    myUConn.Close()
    Return result
End Function

感谢任何帮助!

【问题讨论】:

    标签: .net sql-server


    【解决方案1】:

    在我查看错误可能在哪里之前,我建议您立即停止您的操作,并首先更改所有 sql 代码以使用参数。如果您不这样做,您的网站将受到可能破坏您的数据库的 sql 注入攻击。

    找出问题出在哪里,运行分析器并检查 stmt:starting 和 stmt:completed 事件。

    【讨论】:

      【解决方案2】:

      我对此的看法是在执行命令之前中断。 debug.print 命令文本,切换到 sql 查询分析器并将 sql 字符串粘贴到那里并运行。然后你会确切地看到问题是什么,如果它在命令中。

      我认为您的值可以转义 sql 字符串并包含 '

      【讨论】:

        【解决方案3】:

        除了上面与SQL Injection 相关的其他答案之外,您还需要查看:

        ... " & CoId & " ...
        
        ... " & myCDataReader.GetValue(0) & " ...
        
        ... " & srId & " ...
        

        这些语句没有转义,因此很有可能您的错误在那里。

        【讨论】:

          【解决方案4】:

          将此代码转换为参数化查询(这很可能会修复过程中的错误)所花费的时间很可能比追踪问题所花费的时间更少。没有更多的 SQL 注入风险,更易于阅读,并且您可以获得执行计划。双赢!

          像这样连接字符串很容易出错,这是避免以这种方式执行 SQL 的另一个原因。

          【讨论】:

            【解决方案5】:

            您确定错误在 UPDATE 语句中吗? 我认为它在 SELECT 语句中,正如我从您的堆栈跟踪中看到的那样。为什么不在该语句中也使用参数?

            除此之外,您的代码可以更高效地编写。 现在,您执行一个 SELECT 语句,并且对于结果集中的每条记录,您执行一个 UPDATE 查询。 知道 SQL 是基于集合的,而且这可以写在一条语句中。

            类似的东西:

            UPDATE sr_service
               SET contact_name = vti_ContactInformation.FirstName + ' ' + vti_ContactInformation.LastName
               ... your other columns ..
            FROM vti_ContactInformation
            WHERE sr_service.sr_service_recid = {yourid}
            

            确保将 {yourid} 替换为相应的列。 我没有这样做,因为我无法直接看到您分配给 srId 变量的值。

            【讨论】:

            • 如果我注释掉 ExecuteNonQuery 行,它可以正常运行我没有将其作为一个语句执行的原因是因为如果用户在联系人表中不存在,我不会进行更新,我允许保留默认联系人。
            • 如果用户不存在,那么也不会更新任何内容,因为联系人表中没有记录,还是我的假设有误?
            【解决方案6】:

            首先要做的事;设置为在异常时停止(这样您就可以看到它是哪个非查询)——然后您将能够看到出错的命令文本。

            我还建议将这些查询转换为存储过程(或至少参数化查询);不仅是为了从执行计划中获得性能提升,而且从安全的角度来看(考虑 txtEmail.Text 为 "'; drop table vti_ContactInformation; select '" 时会发生什么

            【讨论】:

              【解决方案7】:

              谢谢大家 - 当我将所有内容更改为参数时,我发现 srId 变量中的值有一些隐藏文本(一些 xml 标签剩余)。一旦我把它理顺了,它就完美地工作了。

              感谢指点和好的方向!

              【讨论】:

              • 我仍然认为你应该能够在一个查询中做到这一点:)
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-07-31
              • 1970-01-01
              相关资源
              最近更新 更多