将 ODBC 链接的 SQL-Table 复制到具有 VBA 的访问 table

Copy a ODBC-linked SQL-Table to an Access table with VBA

我的 Access DB 中有一些 ODBC 链接的 SQL-Server tables,它们是生产环境。为了进行测试,我想将 SQL-Server 中的所有数据复制到结构相同的 Access tables 中,以便我在开发或测试环境中拥有一组相同的 tables .让它变得困难:所有这些 tables 都有自动增量 ID,我希望副本具有相同的值,当然复制的 ID 字段也作为自动增量 long。

所以,这些 table 的一组:
- dbo_tbl_Abcd
- dbo_tbl_Efgh 等等

应复制到:
- Dev_Abcd
- Dev_Efgh 等等

或:
- Test_Abcd
- Test_Efgh 等等

当我对每个单曲进行手动复制和粘贴时 table 这将毫无问题地工作。出现一个对话框 "Paste Table As",您可以在其中选择:

已链接Table
仅结构
结构和数据
将数据附加到现有 Table

正确设置名称并选择“结构”和“数据”后,您将拥有一个与 Access table 相同的正确副本,在自动 ID 字段中具有相同的值。我只想通过代码和所有 ODBC-Table 一次(在一个循环中)执行此操作。当 Access 提供这种手动复制时,必须有一种方法可以通过代码来完成。

我已经试过了:

DoCmd.CopyObject , "Dev_Abcd", acTable, "dbo_tbl_Abcd"

但这只会创建更多指向相同 SQL-服务器 table 的 ODBC 链接。 我也试过这个:

DoCmd.TransferDatabase acExport, "Microsoft Access", CurrentDb.Name, acTable, "dbo_tbl_Abcd", "Dev_Abcd"

这导致了以下错误:
Microsoft Access 数据库引擎找不到该对象。确保该对象存在并且您正确拼写了它的名称和路径名。 (错误 3011)

我对 DoCmd.TransferDatabase 进行了很多试验,但找不到有效的设置。

由于自动增量字段,我没有测试任何 "SELECT INTO"-语句。

我做过类似的事情。将 ConnectionString 更改为您的环境。也许您必须扩展 Translate Datatype 函数。

Function TranslateDatatype(value As Long) As String
  Select Case value
    Case 2: TranslateDatatype = "INT" ' adSmallInt
    Case 3: TranslateDatatype = "LONG" ' adInteger
    Case 200: TranslateDatatype = "STRING" ' adVarChar
    Case 202: TranslateDatatype = "STRING" ' adVarWChar
    Case 17: TranslateDatatype = "BYTE" ' adUnsignedTinyInt
    Case 11: TranslateDatatype = "BIT" ' adBoolean
    Case 129: TranslateDatatype = "STRING" ' adChar
    Case 135: TranslateDatatype = "DATE" ' adDBTimeStamp
    Case Else: Err.Raise "You have to extend TranslateDatatype with value " & value
  End Select
End Function

Sub CopyFromSQLServer()
  Dim SQLDB As Object, rs As Object, sql As String, i As Integer, tdf As TableDef
  Dim ConnectionString As String
  Set SQLDB = CreateObject("ADODB.Connection")
  ConnectionString = "Driver={SQL Server Native Client 11.0};Server=YourSQLServer;Database=YourDatabase;trustedConnection=yes"
  SQLDB.Open ConnectionString
  Set rs = CreateObject("ADODB.Recordset")
  Set rs.ActiveConnection = SQLDB
  For Each tdf In CurrentDb.TableDefs
    rs.Source = "[" & tdf.Name & "]"
    rs.Open
    sql = "("
    i = 0
    Do
      sql = sql & "[" & rs(i).Name & "] " & TranslateDatatype(rs(i).Type) & ", "
      i = i + 1
    Loop Until i = rs.Fields.Count
    rs.Close
    sql = "CREATE TABLE [Dev_" & tdf.Name & "] " & Left(sql, Len(sql) - 2) & ")"
    CurrentDb.Execute sql, dbFailOnError
    sql = "INSERT INTO [Dev_" & tdf.Name & "] SELECT * FROM [" & tdf.Name & "]"
    CurrentDb.Execute sql, dbFailOnError
  Next
End Sub

你问的可以这样

CurrentDb.Execute "select * into localTable from dbo_serverTable" , dbFailOnError

要对所有表执行此操作,请使用此子

   Sub importSrverTables()

    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
    Set db = CurrentDb
    For Each tdf In db.TableDefs       
            If Left(LCase(tdf.Name), 4) = "dbo_" Then
                'CurrentDb.Execute "select * into localTable from  dbo_serverTable", dbFailOnError
                db.Execute "select * into " & Mid(tdf.Name, 5) & " from  " & tdf.Name, dbFailOnError
       ' the next if is to make the loop wait until the transfer finish.
        If db.RecordsAffected > 0 Then
        ' do nothing
        End If
            End If         
    Next
    Set tdf = Nothing
    Set db = Nothing
   End Sub