【问题标题】:Is .ExecuteNonQuery() required to add sql data to a DB in vb.net是否需要 .ExecuteNonQuery() 将 sql 数据添加到 vb.net 中的数据库
【发布时间】:2014-04-07 04:35:11
【问题描述】:

我正在运行以下代码(部分代码)以连接到PHPmyadmin DB

Private Sub sreg_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        SqlConnection.ConnectionString = ServerString



        Try
            If SqlConnection.State = ConnectionState.Closed Then
                SqlConnection.Open()
                MsgBox("Successfully connected to MySQL DB")
            Else
                SqlConnection.Close()
                MsgBox("Connection is Closed")
            End If
        Catch ex As Exception
            MsgBox(ex.ToString)

        End Try
    End Sub

Public Sub SaveNames(ByRef SQLStatment As String)
        Dim cmd As MySqlCommand = New MySqlCommand

        With cmd
            .CommandText = SQLStatment
            .CommandType = CommandType.Text
            .Connection = SqlConnection
            .ExecuteNonQuery()
        End With

        SqlConnection.Close()
        MsgBox("Succesfully Added!")
        SqlConnection.Dispose()
    End Sub 

但是,.ExecuteNonQuery() 在错误和问题方面让我非常头疼。它上传数据,但之前只能执行一次(一次上传),它会返回错误。

当我删除.ExecuteNonQuery() 时没有数据上传?所以我想这是必要的。

这是我上传的代码(部分)

 sql = "INSERT INTO students(student_id, title, initial, surname,
 street, city, pcode, country ) VALUES ('" & strStudent & "', '" 
 & vtital & "', '" & vinital & "', '" & vsurname & "', '" & vstreet 
 & "', '" & vcity & "', '" & vpcode & "', '" & vcountry & "' )"

 SaveNames(sql)

希望我的问题是有意义的,并且我可以传达信息

【问题讨论】:

  • 在你的学生表中是 student_id 主键自动递增吗?您收到的错误信息是什么?
  • `它返回一个错误`WHAT ERROR?
  • @MilenPavlov 是的 student_id 是主键而不是自动递增
  • @walther 我没有收到任何错误消息,它只是退出运行时并说 InvalidOperationException 已处理,然后在 .executenonquery() 下划线
  • 数据类型不匹配。不要用单引号传递 student_id

标签: mysql sql vb.net winforms visual-studio-2010


【解决方案1】:

您保存这些数据的方法存在一些错误,可能会导致您出现问题。
第一个问题是代码不使用参数化查询。这是一个安全问题(Sql Injection),但也是一个简单的逻辑问题。如果你连接字符串来构建一个 sql 查询,你会遇到包含对数据库 sql 引擎具有特殊含义的字符的字符串的问题。如果您的一个字符串包含单引号怎么办?它将被视为字符串的结尾,其余文本为无效 sql。

第二个问题是在异常情况下也缺少 MySqlConnection 的 open/close/dispose。这可以通过使用Using Statement 解决。

所以我会把你的方法重写为

Public SaveNames(ByRef SQLStatment As String, List(Of MySqlParameter) parameters) As Integer
    Using con = new MySqlConnection(... put here the connection string...)
    Using cmd = New MySqlCommand(SQLStatment, con)
         if parameters.Count > 0 Then
            cmd.Parameters.AddRange(parameters.ToArray())
         End If
         return cmd.ExecuteNonQuery()
    End Using
    End Using
End Function

然后用这样的代码调用它

sql = "INSERT INTO students(student_id, title, initial, surname," & _
      "street, city, pcode, country ) VALUES (@id,@title,@init,@sur," & _
      "@street,@city,@pcode,@country)"
Dim ps = New List(Of MySqlParameters)()
Dim p = new MySqlParameter("@id", MySqlDbType.Int32).Value = Convert.ToInt32(strStudent)
ps.Add(p)
p = new MySqlParameter("@title", MySqlDbType.VarChar).Value = vtital
ps.Add(p)
.. and so on for the other parameters. 
.. respecting the actual datatype on the database table
.....
SaveNames(sql, ps)

【讨论】:

  • 谢谢你的回答,我试一试。 1 问SaveName(sql, ps)中的ps代表什么@
  • 关于 open close dispose 我确实有它但没有将它添加到我的代码中,请参阅问题的编辑版本
  • ps是MySqlParameters的列表。有必要将它传递给您的 SaveNames,因为 sql 命令文本包含实际值的占位符,并且这些值与参数列表一起传递。我找不到 MySql 的示例,但是 Sql Server 的许多示例都以相同的方式工作,只是更改了类名。
  • 关于打开/关闭,这样更好,但我仍然认为你不应该保留一个全局变量来存储连接。只需在需要时创建它,以相同的方法打开、使用和关闭/处置。这样,由于异常或其他看不见的问题而导致资源泄漏的可能性较小。 Using Statement
【解决方案2】:

试试这个...

cmd = New MySqlCommand( sqlstatement, conn)
conn.open()

cmd.ExecuteNonQuery()
conn.Close()

正如我建议你..使用参数化

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多