【问题标题】:VB.NET - Getting value from MySQL database and inserting it into Ms. Access (MDB) databaseVB.NET - 从 MySQL 数据库中获取价值并将其插入 Ms. Access (MDB) 数据库
【发布时间】:2020-02-21 01:42:24
【问题描述】:

我想从 MySQL 导出数据库并将其导入 Ms. Access (MDB) 数据库。我尝试编写一个长 LoC 来处理将数据库导入 DataTable 变量并将值存储到其中。

这是我从 MySQL 上的 adm_users 数据库中获取价值的代码

a_query = "SELECT * FROM adm_users where uac_code='4' or uac_code='4A' or uac_code='1'"
a_da = New MySqlDataAdapter(a_query, db_conn)
a_da.Fill(a_ds, "adm_users")
a_dt = a_ds.Tables("adm_users")

然后我想使用此代码将 a_dt 值存储到 MDB 数据库中

For x = 0 To a_dt.Rows.Count - 1
    b_query = "INSERT INTO user_login
               (userid, username, password, uac) VALUES
               ('" + a_dt.Rows(x).Item("userid") + "', '" + a_dt.Rows(x).Item("username") + "', '" + a_dt.Rows(x).Item("userpwd") + "', '2')"
    b_sql = New OleDbCommand(b_query, ms_conn)
    b_sql.ExecuteReader()
Next

然后尝试查找存储在b_query中的字符串查询,看起来像这样

INSERT INTO user_login
                (userid, username, password, uac) VALUES
                ('admin', 'Varenicou', 'administrator', '2')

然后返回值为:“INSERT INTO 语句中的语法错误” 我发现查询没有问题,所以我将 b_query 变量替换为“SELECT FROM user_login”之类的简单查询,返回值为:“SELECT * FROM 语句中的语法错误”

也许我太笨了,不能问这个问题,但我认为 VB.NET 认为我已经打开了与 MySQL 数据库的连接,并且必须始终在 MySQL 数据库上。因此,当我打开与 Access 女士的数据库连接时,它会返回类似的值,并且 VB.NET 与“您想使用哪个数据库?”混淆

我有什么想法来完成这项任务吗?我已经向我的朋友询问了一些建议,他说我需要与班级合作,我也有另一个想法与另一个新项目合作,该项目通过首先将 MySQL 数据库导出为 CSV 来完成输入 Access 女士数据库的任务。

【问题讨论】:

  • 看看参数化你的插入语句,这样的字符串连接总是让人头疼。还要检查您插入的值。您可能会在其中找到特殊字符。错误放置的 ' 可能是导致您的问题的原因
  • 我已尝试将这些查询用于 Access 女士的查询设计。而且效果很好,我得到了我想要的价值。
  • 但是你从 MySQL 中得到的数据呢,里面有什么特殊字符吗?是否有任何数据被插入到您的 mdb 中,或者错误是否发生在第一次循环迭代中?
  • 上面没有任何特殊字符,我在值中添加了 ' ',因为它是“varchar”数据类型。

标签: vb.net


【解决方案1】:

编辑:

重新阅读您的问题后,我可以告诉您,您遇到的具体问题是由于“密码”是 Jet/Access SQL 中的保留字。任何时候想要在 SQL 中使用保留字作为标识符,都需要对其进行转义。对于 Access,您可以通过将其括在括号中来做到这一点,例如

INSERT INTO user_login (userid, username, [password], uac)
VALUES (@userid, @username, @password, @uac)

我在下面的原始建议仍然有效。

原文:

如果您有一个DataTable,那么您就不会遍历它来保存数据。就像您在数据适配器上进行一次Fill 调用以检索数据一样,您也可以进行一次Update 调用来保存数据。当没有什么可读的时候,打电话给ExecuteReader 有什么意义?至少打电话给ExecuteNonQuery,但即使这样也不理想。

如果要插入其中包含的数据,则必须配置第二个数据适配器的InsertCommand。您还需要DataTable 中的所有DataRows 才能拥有RowStateAdded。为此,您只需在第一个数据适配器上将AcceptChangesDuringFill 设置为False。当您调用Fill 时,它会添加所有行,因此它们的RowStateAdded。然后它调用AcceptChanges,将所有RowStates 设置为Unchanged。告诉它不要调用AcceptChanges,你就可以插入了。

这是一个使用两个数据适配器从一个数据库获取数据并插入另一个数据库的示例:

Dim table As New DataTable

Using sourceAdapter As New MySqlDataAdapter("SELECT Column1, Column2 FROM MyTable",
                                            "source connection string here") With {.AcceptChangesDuringFill = False}
    sourceAdapter.Fill(table)
End Using

Using destinationConnection As New OleDbConnection("destination connection string here"),
      destinationCommand As New OleDbCommand("INSERT INTO MyTable (Column1, Column2) VALUES (@Column1, @Column2)",
                                             destinationConnection),
      destinationAdapter As New OleDbDataAdapter With {.InsertCommand = destinationCommand}
    With destinationCommand.Parameters
        .Add("@Column1", OleDbType.VarChar, 50, "Column1")
        .Add("@Column2", OleDbType.Integer, 0, "Column2")
    End With

    destinationAdapter.Update(table)
End Using

如您所见,这是相当简单的事情。一个带有SelectCommand 的数据适配器和另一个带有InsertCommand 的数据适配器。添加参数并没有什么特别之处,但您首先需要了解参数。如果您不知道如何在 ADO.NET 中使用参数,那么您应该立即学习。你可以找到我自己的解释here

【讨论】:

  • 但是,我不能调用我自己已经启动的连接模块吗?
  • “连接模块”是什么意思?如果您只是指创建连接对象的模块,那么您当然可以。我提供的是一个示例。它只是展示了一个原则。您可以以任何您喜欢的方式对其进行调整,以满足您的特定需求。如果您已经有一个连接对象,那么您将其传递给数据适配器构造函数。如果你的意思是你有一个合适的数据访问层,那么它应该已经支持这种类型的功能,或者它不是一个合适的 DAL。如果你有一个循环通过DataTables 并且不使用参数的 DAL,那么它就是需要修复的垃圾。
  • 您编辑的答案是我的问题的实际答案。还是谢谢。
猜你喜欢
  • 2013-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
相关资源
最近更新 更多