2016-10-27 94 views
0

Datagrid to dbf數據庫更新類型的解決方案找不到任何地方,如果有人解決這個問題請回復我。 錯誤 - 對於不返回任何鍵列信息的SelectCommand,不支持UpdateCommand的動態SQL生成。 我的代碼是Datagrid to dbf數據庫使用vb.net

Dim con As New OleDbConnection 
Dim ds As New DataSet 
Dim dt As New DataTable 
Dim da As New OleDbDataAdapter 
Dim con1 As New OleDbConnection 
Dim ds1 As New DataSet 
Dim dt1 As New DataTable 
Dim da1 As New OleDbDataAdapter 


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    con.ConnectionString = "Provider=vfpoledb.1;Data Source=C:\dbf_folder;Collating Sequence=machine;" 
    con.Open() 
    ds.Tables.Add(dt) 
    da = New OleDbDataAdapter("Select * from area.dbf", con) 
    Dim cb = New OleDbCommandBuilder(da) 
    cb.QuotePrefix = "[" 
    cb.QuoteSuffix = "]" 
    da.Fill(dt) 
    dt.Merge(dt1) 
    dbfdatagrid.DataSource = dt.DefaultView 
    con.Close() 
End Sub 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    con1.Close() 
    con1.ConnectionString = "Provider=vfpoledb.1;Data Source=C:\dbf_folder1;Collating Sequence=machine;" 
    con1.Open() 
    da1 = New OleDbDataAdapter("Select * from area.dbf", con1) 
    Dim cb = New OleDbCommandBuilder(da1) 
    cb.QuotePrefix = "[" 
    cb.QuoteSuffix = "]" 
    Dim columns(5) As DataColumn 
    columns(4) = dt.Columns("NAME") 
    dt.PrimaryKey = columns 

    da1.Fill(dt1) 
    da1.Update(dt) 

回答

0

在你的代碼看(我不知道VB,我更多的是C#的傢伙),它不是VFP的事,你的代碼是奇怪給予任何數據庫。

當數據庫是VFP時,您不應該使用這些QuotePrefix和QuoteSuffix。這本身就創建了一個越野車更新命令。您也可以手動編寫更新命令。

儘管我不知道VB,不是你的代碼創建了一個6元素的DataColumn數組,並且只設置了第5個元素,而將其他元素設置爲NULL作爲主鍵?目的是什麼?實際上,如果您沒有有效的主鍵,則不需要指定主鍵(然後您需要手動編寫更新命令 - 如果您可以構建有效的更新命令以正確更新行,這也是您的問題你需要)。我們假設,您將遵循良好的數據庫原則並在表中包含主鍵。那麼你不需要寫手動更新,只需要CommandBuilder爲你構建它。即:

Sub Main() 
    Dim tbl As New DataTable() 

    Dim adapter = New OleDbDataAdapter("select * from Customer", "Provider=VFPOLEDB;Data Source=C:\PROGRAM FILES (X86)\MICROSOFT VISUAL FOXPRO 9\SAMPLES\data") 

    adapter.Fill(tbl) 

    Dim cb = New OleDbCommandBuilder(adapter) 
    adapter.UpdateCommand = cb.GetUpdateCommand() 

    Dim f = New Form() 
    Dim btn = New Button With { 
     .Top = 10, 
     .Text = "Update" 
    } 
    Dim dgv = New DataGridView With { 
     .Top = 50, 
     .DataSource = tbl 
    } 
    f.Controls.AddRange(New Control() {btn, dgv}) 
    AddHandler btn.Click, Sub(sender, args) 
           adapter.Update(tbl) 
          End Sub 

    f.Show() 
End Sub 

如果你有一個表沒有主鍵生成器可以從架構中提取,那麼你可以爲編寫自己手動更新代碼。僅用於採樣,假設您在c:\ Temp中有一個名爲NoPK(v1 i,v2 c(10))的表格。與OleDb的

Sub Main() 
    Dim tbl As New DataTable() 

    Dim adapter = New OleDbDataAdapter("select * from NoPK", "Provider=VFPOLEDB;Data Source=c:\Temp") 

    adapter.Fill(tbl) 

    adapter.UpdateCommand = New OleDbCommand("update NoPK set v2=? where v1=?", adapter.SelectCommand.Connection) 
    adapter.UpdateCommand.Parameters.AddWithValue("p1", "").SourceColumn = "v2" 
    adapter.UpdateCommand.Parameters.AddWithValue("p2", 0).SourceColumn = "v1" 


    Dim f = New Form() 
    Dim btn = New Button With { 
     .Top = 10, 
     .Text = "Update" 
    } 
    Dim dgv = New DataGridView With { 
     .Top = 50, 
     .DataSource = tbl 
    } 
    f.Controls.AddRange(New Control() {btn, dgv}) 
    AddHandler btn.Click, Sub(sender, args) 
           adapter.Update(tbl) 
          End Sub 

    f.Show() 
End Sub 

需要注意的是:雖然它沒有索引信息,它是一個免費的表(生成器無法確定PK),我們知道,V1是我們的重點,我們只想更新V2,可以這樣做,參數應該以命令文本中相應的佔位符(?)以相同的順序添加到集合中(IOW不會先添加p2)。