2011-08-21 66 views
0

我已經看遍了所有的地方,但我似乎無法得到這個工作。使用更新(dataTable)幫助更新訪問數據庫

我想從DataGridView更新Access數據庫。數據庫加載到網格工作正常。我使用this site中描述的說明。

但是,要根據對DataGridView所做更改更新數據庫,我使用命令dataAdapter.Update(datatable);,但取決於位置(此代碼旁邊),代碼將運行但數據庫不會更新。如果我把它放在一個按鈕中,它會拋出一個異常「插入到語句中的語法錯誤」。

其他問題:我應該在加載DataGridView後關閉連接變量嗎?如果是這樣,我應該重新打開它來執行更新,然後重新關閉它?這是如何運作的?。

任何幫助將不勝感激。 編輯:像蒂姆問全班上課。

public partial class Pantalla_Proyecto : Form 
{ 
    private Inicio Inicio; 
    private List<string> Logueado; 
    private OleDbConnection conn; 
    private OleDbDataAdapter Adaptador; 
    private DataTable Tabla; 
    private BindingSource Bsource; 
    private OleDbCommandBuilder Builder; 

    public Pantalla_Proyecto(Inicio Inicio, List<string> Logueado) 
    { 
     this.Inicio =Inicio; 
     this.Logueado = Logueado; 
     InitializeComponent(); 
    } 
    private void Pantalla_Proyecto_Load(object sender, EventArgs e) 
    { 
    } 

    private void importarCDPToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     Importar_CDP Importar_CDP = new Importar_CDP(); 
     Importar_CDP.Show(); 
    } 

    private void importarListasToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     WindowsFormsApplication1.Formularios.Lista_Lazos.Importar_Listas1 Importar_Listas = new WindowsFormsApplication1.Formularios.Lista_Lazos.Importar_Listas1(); 
     Importar_Listas.Show(); 
    } 

    private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 

    } 

    private void flowLayoutPanel2_Paint(object sender, PaintEventArgs e) 
    { 

    } 

    private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
    { 

    } 

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     string sql = "Select * From ["+TABLE (THIS IS A STRING I GET FROM PREVIOUS FORM)+"]"; 
     conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=proyectos\" + Location(this is a string i get on the previous form) + ".mdb;User Id=admin;Password=;"); 
     conn.Open(); 

     // Extraemos info de mi database y la meto en un datatable 
     Adaptador = new OleDbDataAdapter(sql, conn); 
     Builder = new OleDbCommandBuilder(Adaptador); 
     Tabla = new DataTable(); 
     Adaptador.Fill(Tabla); 

     // LLENO EL DATA GRID VIEW 
     Bsource = new BindingSource(); 
     Bsource.DataSource = Tabla; 
     dataGridView1.DataSource = Bsource; 
     dataGridView1.Dock = DockStyle.Fill; 
     Adaptador.Update(Tabla);//if i put it here nothing happens 
     conn.Close(); 


    } 

    private void dataGridView1_Validating(object sender, CancelEventArgs e) 
    { 

    } 

    private void button1_Click_1(object sender, EventArgs e) 
    { 
     conn.Open(); 
     Adaptador.Update(Tabla);//IF i put it here i get an exception 
     conn.Close(); 
    } 
+0

你能展示更多的代碼嗎?特別是發生錯誤的地方。至於關閉連接,是的,每當你完成時你應該關閉它。最好將連接包裝在一個使用語句中,該語句將自動處理關閉它。 – Tim

+0

你能詳細說明一下使用語句嗎?,我對編程相當陌生 – Joaquin

+0

我添加了一個涵蓋using語句和其他一些事情的答案。 – Tim

回答

1

爲了詳細咬傷,按OP的要求,在使用的語句,讓我們的comboBox1_SelectedIndexChanged方法:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    string sql = "Select * From ["+TABLE (THIS IS A STRING I GET FROM PREVIOUS FORM)+"]"; 

    using (conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=proyectos\" + Location(this is a string i get on the previous form) + ".mdb;User Id=admin;Password=;")) 
    { 
     conn.Open(); 

     // Extraemos info de mi database y la meto en un datatable 
     Adaptador = new OleDbDataAdapter(sql, conn); 
     // Remove the OleDbCommandBuilder 
     Tabla = new DataTable(); 
     Adaptador.Fill(Tabla); 

     // LLENO EL DATA GRID VIEW 
     Bsource = new BindingSource(); 
     Bsource.DataSource = Tabla; 
     dataGridView1.DataSource = Bsource; 
     dataGridView1.Dock = DockStyle.Fill; 
     // ** NOTE: 
     // At this point, there's nothing to update - all that 
     // has happened is that you've bound the DataTable 
     // to the DataGridView. 
     Adaptador.Update(Tabla);//if i put it here nothing happens 

    } // Your connection will be closed at this point when the using 
     // statement goes out of scope. 
} 

UPDATE

MSDN說:「當你創建一個新的實例OleDbCo mmandBuilder,與這個OleDbDataAdapter相關的任何現有的OleDbCommandBuilder被髮布。「然而,如果你想完全脫離OleDbCommandBuilder,你可以這樣做(我更新了我的代碼,以做到這一點)。既然你認爲你有特殊字符的問題,這樣做可能是值得的。

像這樣的東西應該幫助 - 你必須根據修改更新命令你的表列如下:

private void button1_Click_1(object sender, EventArgs e) 
{ 

    conn.Open();   
    Adaptador.UpdateCommand = "<Your SQL here>" // I.e., UPDATE [TABLE] SET.... 
    try 
    { 
     Adaptador.Update((DataTable)Bsource.DataSource); 
    } 
    catch (Exception ex) 
    { 
     // Do something with the exception 
    } 
} 

這段代碼是什麼MSDN有一個稍微修改後的版本:

How to: Bind Data to the Windows Forms DataGridView Control

請注意,它們在示例中使用了SqlDbCommandBuilder,但總體原則保持不變。

根據David-W-Fenton的評論,您可能希望在Form_Load事件中執行連接和數據適配器初始化,然後關閉Form_Closing事件上的連接。

+0

hmmmm那是什麼? :S,也許就是這樣,我只是按照網站的說明,它說所有的sql指令都將由Oldbcommand Builder自動生成,我應該在Updatecommand?中寫一個sql指令? – Joaquin

+0

@Joaquin - 我認爲(我從來沒有這樣做過,只是脫離MSDN文檔),您必須在OleDbAdapter上設置Select命令來自動生成剩餘的命令。我編輯了我的答案以反映這一點。 – Tim

+0

我找到了錯誤,我的commandbuilder沒有讓我插入,刪除或更新命令!在我的dataadapter它們都是空的時發生異常,所以自然有一個例外,當我嘗試插入或更新...現在的問題是爲什麼它們爲空? 我做了你說什麼tim oledbcommand comando = new oledbcommand(sql,conn); Adaptador.selectcommand = comando; 但我得到了同樣的結果.... 值得注意的是,即使在做這個之前,我的select命令被設置爲「sql」字符串中的一個,所以選擇不是問題..它是什麼? – Joaquin

0

首先要檢查的是您實際更新的Access文件的運行時路徑。

如果您使用VS.NET,MDB文件是您的項目的一部分,並且MDB文件上的「Copy Local」選項設置爲true,那麼它可能就是您每次運行您的程序會覆蓋上次執行的更新。

我只是提,因爲我已經被這個;-)

乾杯