2017-01-20 318 views
0

我有一个XML文件,在“/ response/result/record”下有很多记录。例如:将XML数据导入到MS Access表中使用SQL和VB6

<response> 
    <result> 
    <record> 
     <flda>some text</flda> 
     <fldb>some text</fldb> 
     :  :  : 
    </record> 
    : : : 
    </result> 
</response> 

我有一个MSACCESS数据库和需要读取这个文件,并将其加载到包含字段中每个记录的每个文本节点表中的遗留VB6程序。

我知道我可以使用MSXML2.DOMDocument从互联网加载XML并可能将其保存到文件中。然后,我也可以使用DOMDocument读取XML并一次加载一条记录到MSAccess数据库表中。

这似乎是低效的,因为我可以使用VB6语法如CSV文件加载到一个MSACCESS表:

db.Execute "Select * Into CSVtable From [Text;FMT=CSVDelimited;HDR=YES;DATABASE=dirPath].[filename]" 

,它会很快批量加载数据到数据库中。很多,比从CSV文件中读取每条记录并使用DAO记录集一次添加每条记录要快得多。

我的问题:我可以用XML文件做同样的事吗?什么是语法,我该怎么做?

后续问题:我在哪里可以找到关于这个时髦的'Select ...'语法的文档,我上面显示了CSV文件(我最初在StackOverflow中找到)?

+0

[这个问题](http://stackoverflow.com/q/365312/2144390)有几个答案,提出了将XML数据转换为CSV格式的方法,之后您可以使用您描述的方法导入CSV。 –

回答

1

您所需的SELECT语法只能在我能确定的JETSQL40.CHM文档中定义。这通常与MS Office 2000或更高版本一起安装,但您必须在“Program Files”特殊文件夹中进行挖掘才能找到它。那里有足够的有用的东西,我通常自己创建一个快捷方式。

但是,由于没有Jet XML 可安装的ISAM(IISAM),您将不得不做一些MS Access自身导入XML格式数据的事情。

虽然这涉及到循环,但您可以以比通常人更优化的方式进行批量插入。下面使用的代码试图做到这一点。

这个程序有一个形成一个单一的菜单项mnuImportXML和一个MSHFlexGrid命名FlexGrid在它创建的第一次运行该数据库显示“记录”表的内容:

Option Explicit 

Private Const CONNWG As String = "Provider=Microsoft.Jet.OLEDB.4.0;" _ 
           & "Jet OLEDB:Engine Type=5;" _ 
           & "Jet OLEDB:Create System Database=True;" _ 
           & "Data Source='$DB$.mdw';" 
Private Const CONNDB As String = "Provider=Microsoft.Jet.OLEDB.4.0;" _ 
           & "Jet OLEDB:Engine Type=5;" _ 
           & "Jet OLEDB:System Database='$DB$.mdw';" _ 
           & "Data Source='$DB$.mdb';" 

Private CN As ADODB.Connection 
Private QueryRS As ADODB.Recordset 
Private UpdateRS As ADODB.Recordset 
Private XmlRS As ADODB.Recordset 
Private recordsRS As ADODB.Recordset 
Private AppendFields As Variant 

Public Function OpenConnection(ByVal DbPath As String) As ADODB.Connection 
    Dim ExtensionPos As Long 

    ExtensionPos = InStrRev(DbPath, ".") 
    If ExtensionPos > 0 Then DbPath = Left$(DbPath, ExtensionPos - 1) 
    On Error Resume Next 
    GetAttr DbPath & ".mdb" 
    If Err Then 
     On Error GoTo 0 
     Set OpenConnection = CreateDB(DbPath) 
    Else 
     On Error GoTo 0 
     Set OpenConnection = New ADODB.Connection 
     OpenConnection.Open Replace$(CONNDB, "$DB$", DbPath) 
    End If 
End Function 

Private Function CreateDB(ByVal DbPath As String) As ADODB.Connection 
    Dim catDB As Object 'Don't early-bind ADOX objects. 

    Set catDB = CreateObject("ADOX.Catalog") 
    With catDB 
     .Create Replace$(CONNWG, "$DB$", DbPath) 
     .Create Replace$(CONNDB, "$DB$", DbPath) 
     Set CreateDB = .ActiveConnection 
     Set catDB = Nothing 
    End With 
    With CreateDB 
     .Execute "CREATE TABLE [Records](" _ 
       & "[ID] IDENTITY CONSTRAINT PK_UID PRIMARY KEY," _ 
       & "[flda] TEXT(255) WITH COMPRESSION," _ 
       & "[fldb] TEXT(255) WITH COMPRESSION)", , _ 
       adCmdText Or adExecuteNoRecords 
    End With 
End Function 

Private Sub RefreshGrid() 
    QueryRS.Open "[Records]", , , adLockReadOnly, adCmdTable 
    Set FlexGrid.DataSource = QueryRS 
    QueryRS.Close 
End Sub 

Private Sub Form_Load() 
    Set CN = OpenConnection("demo.mdb") 
    Set QueryRS = New ADODB.Recordset 
    QueryRS.CursorLocation = adUseClient 
    Set QueryRS.ActiveConnection = CN 
    Set XmlRS = New ADODB.Recordset 
    XmlRS.ActiveConnection = "Provider=MSDAOSP;Data Source=MSXML2.DSOControl.3.0" 
    Set UpdateRS = New ADODB.Recordset 
    Set UpdateRS.ActiveConnection = CN 
    UpdateRS.Properties("Append-Only Rowset").Value = True 
    AppendFields = Array("flda", "fldb") 
    RefreshGrid 
End Sub 

Private Sub Form_Resize() 
    If WindowState <> vbMinimized Then 
     FlexGrid.Move 0, 0, ScaleWidth, ScaleHeight 
    End If 
End Sub 

Private Sub Form_Unload(Cancel As Integer) 
    CN.Close 
End Sub 

Private Sub mnuImportXML_Click() 
    XmlRS.Open "response.xml" 
    Set recordsRS = XmlRS.Fields("record").Value 
    UpdateRS.Open "Records", , , adLockOptimistic, adCmdTableDirect 
    CN.BeginTrans 
    With recordsRS 
     Do Until .EOF 
      UpdateRS.AddNew AppendFields, _ 
          Array(.Fields(AppendFields(0)).Value, _ 
            .Fields(AppendFields(1)).Value) 
      .MoveNext 
     Loop 
    End With 
    CN.CommitTrans 
    UpdateRS.Close 
    Set recordsRS = Nothing 
    XmlRS.Close 
    RefreshGrid 
End Sub 

这里的关键是菜单事件处理程序mnuImportXML_Click(向下滚动到结尾),其将重复的第二级XML元素和fldb的子元素的文本附加到Jet数据库表Records中的子元素record

的使用注意事项的:

UpdateRS.Properties("Append-Only Rowset").Value = True 

即内的Form_Load初始化期间完成。它有点提高了性能。

我不知道有任何更快的方法来完成此操作。 Jet不能将XML文档用作外部数据库。它只能使用具有IISAM的数据库类型,例如Text,HTML,Excel 8.0,dBase IV和Paradox。

无论微软是否懒惰,并且毫不犹豫地将XML留在Jet 4.0之外,XML文档的层次性并没有给他们留下很多选择,而没有扩展Jet SQL语法,或者存在一些我没有找到的语法。我只是不能说。

相关问题