【问题标题】:Conversion from string "The INSERT INTO statement contai" to type 'Boolean' is not valid从字符串“INSERT INTO statement contai”到类型“Boolean”的转换无效
【发布时间】:2015-10-09 22:51:05
【问题描述】:

我正在 MSVStudio 中创建注册表单,但总是出现错误。我已经将每个变量设置为它们自己的数据类型,但同样的错误提示给我。 "从字符串 "The INSERT INTO statement contai" 到类型 'Boolean' 的转换无效。"

这是我在课堂上的功能

  Function registercust(ByVal a As String, ByVal b As String, ByVal c As String, ByVal d As String, ByVal f As String, ByVal g As String, ByVal h As DateTime, ByVal i As String, ByVal j As String)
    Dim conn As New OleDb.OleDbConnection
    Dim dr As OleDb.OleDbDataReader
    Dim rs As New OleDb.OleDbCommand
    Try
        conn.ConnectionString = cs
        conn.Open()
        query = "Insert into custinfo (`custid`,`lastname`,`firstname`,`mi`,`address`,`telephone`,`birthday`,`age`,`status`) values('" & a & "','" & b & "','" & c & "','" & d & "','" & f & "','" & g & "','" & h & "','" & i & "','" & j & "')"
        rs = New OleDb.OleDbCommand(query, conn)
        dr = rs.ExecuteReader
        If dr.Read Then
            Return True
        Else
            Return False
        End If

    Catch ex As Exception
        Return ex.Message
    End Try
    conn.Close()
End Function

这是我的代码哟我的按钮

 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    If class1.chkfieldss(TextBox14.Text, TextBox1.Text, _
                          TextBox8.Text, TextBox9.Text, _
                          TextBox10.Text, TextBox11.Text, TextBox12.Text) = False Then
        If class1.registercust(TextBox14.Text, TextBox1.Text, TextBox8.Text, TextBox9.Text, TextBox10.Text, _
                               TextBox11.Text, DateTimePicker1.Value, _
                               TextBox12.Text, ComboBox3.SelectedItem) = False Then

            MessageBox.Show("REGISTER SUCCESSFULLY", "Welcome", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        Else
            MessageBox.Show("Something Happen", "Error", MessageBoxButtons.OK, _
                            MessageBoxIcon.Error)
        End If

    Else
        MessageBox.Show("Complete all fields", "Error", MessageBoxButtons.OK, _
                           MessageBoxIcon.Error)
    End If
End Sub

【问题讨论】:

  • 您的撇号在指定的插入列上看起来很奇怪。值上的撇号看起来很正常。除此之外,您绝对应该使用用户参数化 SQL
  • 实际上,您的代码充满了各种各样的问题。请在下面查看我的答案,以了解其中至少一些已解决
  • 您的函数显然设计为返回一个布尔值,但在异常情况下,您尝试返回一个字符串。将Option Strict On 放在代码顶部或在项目设置中打开它。顺便说一句,如果出现异常,您的conn.Close() 将永远不会被调用。您应该始终使用 Using 块内的连接。

标签: vb.net boolean syntax-error


【解决方案1】:

您是关闭strict compiler option 的又一个受害者。这应该始终开启。


您尚未为函数 registercust 定义返回类型。我应该期待一个布尔值还是一个字符串?

Function registercust(...) '<- As surprise?

您的查询失败,可能是由于您创建查询的方式很糟糕。 始终使用prepared statements。函数返回错误信息(字符串)"The INSERT INTO statement contai...".

Return ex.Message

现在,回到Button2_Click 方法,您尝试将返回值与布尔值进行比较。

If class1.registercust(...) = False Then

这是您的代码分解的地方。您不能将值“INSERT INTO 语句包含...”(字符串)转换为FalseTrue(布尔值)。

【讨论】:

    【解决方案2】:

    您的插入语句中有错误。使用调试方法来识别错误。使用参数化查询总是更好。

    这将有助于防止 SQL 注入攻击以及有助于省略用户输入中的引号等连接错误 (')

    【讨论】:

      【解决方案3】:

      你的函数应该是这样的 - 见代码 cmets

      ' you should really pass customer model with properties here instead of all these arguments
      Public Class Customer
          Public Property CustId As String
          Public Property LastName As String
          Public Property FirstName As String
          Public Property Mi As String
          Public Property Address As String
          Public Property Telephone As String
          Public Property Birthday As String
          Public Property Age As String
          Public Property Status As String
      End Class
      . . . . . . . . . 
      Function RegisterCust(ByVal c As Customer) As Boolean '<-- add returning type
      
          Dim retVal As Boolean
      
          ' "Using" helps to dispose of objects that implement IDisposable
          ' Try to avoid oledb provider altogether for RDBMSs
          Using conn As OleDb.OleDbConnection = New OleDb.OleDbConnection(cs) ' pass conn str on creation
              ' This makes for clean code
              Dim query As String = "Insert into custinfo " & 
                  "(custid, lastname, firstname, mi, address, telephone, birthday, age, status) values " & 
                  "('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}')" 
              query = String.Format(query, c.CustId, c.LastName, c.FirstName, c.Mi, c.Address, c.Telephone, c.Birthday, c.Age, c.Status)
      
              ' Now, this query above "all good and dandy" but it is vulnerable to sql injection. 
              ' To prevent it, instead of  '{1}', you would type something like @1, or if you want, @lastname - a parameter name
              ' Then, add a parameter with your value to cmd.parameter collection.
      
              Using cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand(query, conn)
      
                  conn.Open()
      
                 ' your query doesn't need reader. You inserting value without returning anything 
                 retVal = cmd.EcecuteNonQuery() > 0 ' Assign return value
      
             End Using ' cmd
             conn.Close()
          End Using ' conn
      
          return retVal
      End Function
      

      我删除了异常处理,因为您没有真正的处理。使用using,您至少可以确保对象在此方法退出之前关闭。如果你愿意,你可以把整个东西包装到 try-block 中

      这不是你必须做的,但它是一种很好的格式

      【讨论】:

      • 这段代码仍然很容易受到 sql 注入攻击。您应该使用准备好的查询。
      • @ChrisDunaway 我同意,但我从未声称这段代码是完美的和防弹的。这是一种尝试展示这种更简洁代码的方法之一。几乎任何有类似问题的人都将这个漏洞写入其中。我只是不能一直谈论它。所以我把它排除在这个答案之外。但是为了取悦你和其他任何人,我添加了一条指向这个问题的评论。谢谢
      • 如果您要通过重写代码来清理它的麻烦,只需编写参数化的 sql 代码即可。几乎没有更多的努力。
      猜你喜欢
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 2015-02-09
      • 1970-01-01
      相关资源
      最近更新 更多