从Access数据库表到MySQL远程数据库的插入/复制记录一一对应

时间:2019-01-10 10:06:10

标签: mysql vb.net ms-access server

我想将表记录从Access数据库插入到MySQL远程服务器。

我的方法是:

  • 在带有循环的TextBox中从第一条记录到最后一条记录加载Access数据库
  • 检查记录是否已插入MySQL远程数据库中
  • 如果没有,则一个接一个地插入

代码产生错误消息:

  

该值不能为空参数模式:数据源

我的代码在这里:

SQLda = New MySqlDataAdapter(("INSERT INTO approved (word, approveds) Select * FROM (SELECT '" & TextBox3.Text & "', 'No') AS tmp WHERE Not EXISTS (SELECT word FROM approved WHERE word= '" & TextBox3.Text & "') LIMIT 1"), MysqlConn)

MysqlConn = New MySqlConnection
ListBox1.Items.Clear()

MysqlConn.ConnectionString = "server=localhost;userid=root;password=;port=3306;database=sindhila_spellchecker;Character Set=utf8;SslMode=none;"

SQLda = New MySqlDataAdapter(("SELECT * FROM approved"), MysqlConn)
SQLda.Fill(dbds, "doctors")
DataGridView1.DataSource = dbds.Tables("doctors")

Try
    MysqlConn.Open()
    MessageBox.Show("Connection Successful, click ok to continue")
    Label3.Visible = True

    romantranssql = "Select * from approved order by id"

    pth = My.Application.Info.DirectoryPath
    romantransconn.ConnectionString = "Provider=Microsoft.ace.oledb.12.0; Data Source=" & pth & "\database.mdb; User Id=admin; Password=;"
    romantransda = New OleDbDataAdapter(romantranssql, romantransconn)
    romantransds = New DataSet
    romantransda.Fill(romantransds, "DisplayCenterData")
    romantransdt = romantransds.Tables("DisplayCenterData")
    romantranscmb = New OleDbCommandBuilder(romantransda)

    Do Until Me.BindingContext(romantransdt).Position = Me.BindingContext(romantransdt).Count - 1

        TextBox3.DataBindings.Clear()
        TextBox3.DataBindings.Add("text", romantransdt, "word")

        MysqlConn = New MySqlConnection

        MysqlConn.ConnectionString = "server=localhost;userid=root;password=;port=3306;database=sindhila_spellchecker;Character Set=utf8;"

        SQLda = New MySqlDataAdapter(("INSERT INTO approved (word, approveds) Select * FROM (SELECT '" & TextBox3.Text & "', 'No') AS tmp WHERE Not EXISTS (SELECT word FROM approved WHERE word= '" & TextBox3.Text & "') LIMIT 1"), MysqlConn)
        SQLda.Fill(dbds, "approved")

        DataGridView1.DataSource = dbds.Tables("approved")
        romantransdtx = dbds.Tables("approved")
        Me.BindingContext(romantransdtx).Position = 0
        Me.BindingContext(romantransdt).Position = Me.BindingContext(romantransdt).Position + 1
        Me.Refresh()
    Loop

    MsgBox("all New records have been uploded To server")
    Label3.Visible = False

    MysqlConn.Close()

Catch ex As Exception
    MessageBox.Show(ex.Message)
Finally
    MysqlConn.Dispose()

End Try

2 个答案:

答案 0 :(得分:1)

这不是对您问题的确切/直接答案,而是更多建议

老实说,您的代码看起来很丑陋,有时也没有任何意义。让我们从丑陋开始。这是我最喜欢的报价(顺便说一句,是我的报价):

  

您将花费20%的时间编写代码,并花费80%的时间维护代码。

您知道大型组织中有多少开发人员因缺乏经验的程序员编写的拙劣代码而感到沮丧吗?有时,他们甚至不得不从头开始编写东西以修复问题。您的整个代码写得不好,我几乎可以在每行上指出一个错误。例如,

为什么

MysqlConn = New MySqlConnection
MysqlConn.ConnectionString = "...."

可以在哪里完成

MysqlConn = New MySqlConnection("....")

是的,甚至单行代码也很重要。它可能对执行没有任何影响,但对其外观有很大影响。尝试解决这些问题。

现在,让我们谈谈那里有一些无用的代码。

SQLda = New MySqlDataAdapter(("INSERT INTO.....")), MysqlConn)
...
SQLda = New MySqlDataAdapter(("SELECT * FROM approved"), MysqlConn)

如果SQLda在分配新值之前没有被使用,那么首先给它分配值有什么用?好吧,如果您没有发布完整的代码,我可能在这里错误。

现在,您在这里使用Try-Catch语句。为什么通过使用类Exception捕获所有可能的异常,而您只能捕获在这里可能真正发生的特定异常,例如{ {1}}?捕捉(Exception)是一个坏主意。 Read more here

您正在打开与数据库的连接,完成操作后,将其关闭并处置(通过调用SqlException方法)。当Dispose类已经实现了Using时,为什么只使用SqlConnection语句,为什么还要这么忙呢?

因此,代替此:

IDisposable

执行此操作

 Dim MySqlConn = New SqlConnection("...")
 MySqlConn.Open()
 .....
 .....
 MySqlConn.Close()
 MySqlConn.Dispose()

一些最后的词

您的代码使我觉得您的项目很小。但是对于将来的项目,强烈建议遵循以下建议:

  • 切勿将连接字符串存储在代码或本地文件中

将连接字符串存储在配置文件中,例如Using MySqlConn = New SqlConnection("....") ... End Using app.config文件中。

  • 切勿直接将值传递给SQL语句,而应使用参数

编写代码以传递直接值只会打开SQL注入的大门。因此,请始终传递参数。

  • 不隐藏/显示控件,而是在需要时从代码隐藏中创建/删除它们

您可以在表单中创建一个控件(在您的情况下为web.config)并隐藏它,然后在需要时显示它。但这会浪费您的资源。如果您使用的是1个甚至5个标签,则可能不会消耗太多的资源...但是我们不仅仅拥有一个仅包含标签的UI,对吗?您很快就会意识到,毫秒级的执行或性能提升将走很长一段路。因此,在必要时以编程方式创建/删除控件。这将为Label带来巨大的帮助。

  • 切勿在不正确理解的情况下使用任何对象/类/任何东西

您正在使用GarbageCollector s。您知道它消耗多少内存吗?一个更简单的选择是像DataTable这样的IEnumerable(T)(通用列表)。就性能而言,甚至是简单的List也是更好的选择。

  • 始终添加有用的评论

开发人员社区中有一个臭名昭著的模因。它是这样的:

  

当我编写代码时,只有上帝和我知道它是如何工作的   ...   现在只有上帝知道它是如何工作的。

始终在代码中添加有用的注释。这可能不会直接给您带来好处,但会帮助将来调试您代码的开发人员。另外,在Visual Studio中,添加DataReader关键字以将代码划分为多个部分。

我想现在已经足够了。我希望这对您有用。

干杯!

答案 1 :(得分:0)

您不为自动增量字段插入值。以下内容适用于我使用的一些测试数据库。

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim RetVal As Integer
    Dim InsertQuery = "INSERT INTO dbusers (myuser, mypassword)
                      Select  @name, @pass
                      WHERE Not EXISTS
                      (SELECT * FROM dbusers WHERE myuser = @name AND mypassword = @pass);"
    Using cn As New MySqlConnection(My.Settings.dbusersConnection)
        Using cmd As New MySqlCommand(InsertQuery, cn)
            cmd.Parameters.Add("@name", MySqlDbType.VarChar).Value = TextBox1.Text
            cmd.Parameters.Add("@pass", MySqlDbType.VarChar).Value = TextBox2.Text
            cn.Open()
            RetVal = cmd.ExecuteNonQuery
        End Using
    End Using
    If RetVal = 1 Then
        MessageBox.Show("Success")
    Else
        MessageBox.Show("Failure")
    End If
End Sub