2014-07-09 141 views
-1

我知道這會很簡單,但我不知道我的代碼有什麼問題。我已經嘗試過好幾次了。 我有兩件事,用戶名爲&我的數據庫表上的密碼。我想將數據添加到DataGridView並將其保存到我的數據庫表。我使用2個按鈕ADD & SAVE。如何使用VB.NET將數據添加到MS Access數據庫?

數據庫表

ID Username Password 
1 Zain  12345 
2 Admin  root 

VB.NET代碼(如https://www.youtube.com/watch?v=XRVBpTFa3To解釋)

Public Class edmin 

Private Sub edmin_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    'TODO: This line of code loads data into the 'UserInfoDataSet1.Users' table. You can move, or remove it, as needed. 
    Me.UsersTableAdapter.Fill(Me.UserInfoDataSet1.Users) 

End Sub 

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    UsersBindingSource.AddNew() 

End Sub 

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 
    Try 
     UsersBindingSource.EndEdit() 
     UsersTableAdapter.Update(UserInfoDataSet1.Users) 
     MessageBox.Show("Saved") 
    Catch ex As Exception 
     MessageBox.Show("error") 

    End Try 
End Sub 

末級

+0

那麼你期望發生什麼,實際發生了什麼?我不會去YouTube找出你可以在這裏解釋的。 – jmcilhinney

+0

@jmcilhinney我想使用2個文本框和ADD&SAVE按鈕將數據插入到MS Access表中...... 但是我得到了-1的值,並且數據無法保存在MS Access表中。 – user3822131

+0

-1是由'DataTable'生成的臨時ID。最終的ID由數據庫在保存數據時生成。你怎麼知道數據無法保存?無論是保存還是拋出異常。如果拋出異常,那麼錯誤信息是什麼?如果沒有例外,那麼數據將被保存。 – jmcilhinney

回答

0

當添加一個數據文件時,例如MDB或ACCDB,您的項目,它成爲一個源文件。當您在調試器中運行項目時,您的應用程序不會連接到該數據庫。當您構建時,該源數據文件將與您的EXE一起復制到輸出文件夾,並且它是您在運行時連接的副本。如果你在源文件中查找測試期間添加的任何數據,當然你不會找到它。

當你考慮它時,這是非常有意義的。當需要部署應用程序時,您是否真的需要花時間清理數據庫,將其置於適合分發的狀態?通過對副本進行測試,可以使源數據庫保持原始狀態。當您構建應用程序的發行版時,乾淨的源數據庫將使用EXE複製到發行版輸出文件夾中,並且您的用戶將獲得該乾淨的副本。

現在,將數據庫添加到項目時,默認情況下,其Copy to Output Directory屬性設置爲Copy always。這意味着每次構建項目時都會創建一個新副本。如果運行項目並對數據庫進行更改,則停止調試程序,更改代碼並再次運行項目,重建項目並創建新的數據庫副本,從而使更改消失。如果您在不對代碼進行任何更改的情況下運行該項目兩次,那麼將不會再次構建它,以免重寫工作數據庫中的更改。

您應該做什麼 - 以及我認爲Microsoft應該默認完成的操作 - 將Copy to Output Directory屬性更改爲Copy if newer。這樣,即使您的項目已建好,除非您對源數據庫進行了更改,否則不會創建新的數據庫副本。這將允許您保持相同的測試數據在您的工作數據庫中,只要您想要。當您確實想重新開始時,只需手動從輸出文件夾中刪除數據文件或更改Copy to Output Directory即可獲得單個版本。

由於源文件可能會更改,即使您不更改其中包含的數據或模式,Microsoft也會對此提出警告。簡單地打開文件會影響它,並提示新的副本覆蓋你的工作目錄。如果每次都會創建一個新副本,我會說大吶。當我不打算這樣做時,我很少看到數據文件更新。您可以read here瞭解更多信息。

現在,關於ID,當您添加新行時,您的DataTable將創建一個臨時ID。只要您在應用程序中使用數據而不將其提交到數據庫,該ID就可以用於識別該行,甚至可以識別相關的子行。當您提交更改時,數據庫會生成一個永久ID。

通常情況下,您不需要那個ID就可以了,因爲您不會那時使用數據。如果不再次檢索數據,您將不會再使用這些數據,在這種情況下,您將使用它檢索最終的ID。有時候,你確實想要立即檢索最終的ID。其中一個必要的場景是保存父記錄和一個或多個子記錄的位置。保存父記錄時,您需要從數據庫獲取最終的ID並將其放回DataTable,以便在保存子行之前更新子行中的外鍵值。如果你沒有這樣保存子行,那麼你將違反數據庫中的外鍵約束,並拋出一個異常。

一些數據提供者,例如,用於SQL Server的SqlClient,每個命令支持多個SQL語句。在這種情況下,您可以簡單地在INSERT聲明後添加SELECT聲明,並且無需額外代碼即可將新ID恢復到DataTable中。不幸的是,Jet和ACE OLE DB提供程序不支持每個命令的多個SQL語句。因此,當插入記錄時,你必須寫一些代碼來明確地檢索新的ID。這裏是你如何能做到與類型化的DataSet的快速代碼示例:

''' <summary> 
''' Handles the RowUpdated event of the parent adapter. 
''' </summary> 
''' <param name="sender"> 
''' The adapter that saved the row. 
''' </param> 
''' <param name="e"> 
''' The data for the event. 
''' </param> 
''' <remarks> 
''' This event handler is used to retrieve an auto-generated ID from the database after a row is inserted and update the corresponding row in the local data set. 
''' </remarks> 
Private Sub parentAdapter_RowUpdated(sender As Object, e As OleDbRowUpdatedEventArgs) 
    'We are only interested in new records. 
    If e.StatementType = StatementType.Insert Then 
     'Get the last ID auto-generated by the database. 
     Dim lastAutoNumber = Me.parentAdapter.GetLastAutoNumber().Value 

     'Update the ID of the local row. 
     DirectCast(e.Row, ParentChildDataSet.ParentRow).ParentID = lastAutoNumber 
    End If 
End Sub 

在這種情況下,GetLastAutoNumber是我加入到DataSet設計的表適配器查詢。這是一個標量查詢簡單地包含以下SQL:

SELECT @@IDENTITY 

你可以找到完整的示例here

+0

我注意到我的錯誤,我在Access數據庫表中使用密碼作爲字段名稱。 *密碼是保留值。* 現在我的代碼完美無缺。 :) 謝謝@ jmcilhinney – user3822131

相關問題