2017-01-20 229 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語法,或者存在一些我沒有找到的語法。我只是不能說。

相關問題