Dùng VB.NET, truy xuất database bằng các đối tượng OleDb, khi sử dụng lệnh truy vấn "Update" thì nhận thấy giá trị Update không kịp. Cụ thể tôi có 1 file database Access có tên là db1.mdb, bên trong database có 1 bảng dữ liệu tên là Table1, mỗi record của bảng Table1 có 1 field tên là Col1 thuộc kiểu số nguyên. Tôi viết 1 ứng dụng nhỏ gồm 1 form chứa 2 button: Khi click chuột vào Button2, chương trình sẽ cập nhật nội dung field Col1 (của tất cả record của bảng Table1) về giá trị 1234, còn khi click chuột vào Button1 thì chương trình sẽ cập nhật field Col1 (của tất cả record) về giá trị 4 rồi hiển thị giá trị vừa cập nhật để kiểm tra, nhưng thật bất ngờ kết quả hiển thị của field Col1 không bằng 4 mà bằng 1234. Như vậy lệnh Update chưa cập nhật kịp dữ liệu lên database. Xin hỏi nguyên nhân và cách khắc phục. Toàn bộ code VB .Net của ứng dụng như sau:

'nhập cảng các class Oledb
Imports System.Data.OleDb
'đặc tả form ứng dụng
Public Class Form1
'định nghĩa các thuộc tính cần dùng
Dim PathFileName As String = Application.StartupPath & "\db1.mdb"
Dim CnnMain As OleDbConnection

'thủ tục tạo kết nối đến database
Sub Ketnoi_OleDb()
CnnMain = New OleDbConnection
CnnMain.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileName & ";Persist Security Info=False"
CnnMain.Open()
End Sub

'thủ tục khởi tạo form ứng dụng
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'tạo kết nối đến database
Call Ketnoi_OleDb()
End Sub

'thủ tục xử lý click chuột trên Button2
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnGan.Click
'cập nhật field Col1 về giá trị 1234
Dim myOleDbCommand As New OleDbCommand("UPDATE Table1 SET Col1=1234", CnnMain)
myOleDbCommand.ExecuteNonQuery()
End Sub

'thủ tục xử lý click chuột trên Button1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSuavaNhan.Click
Dim da As OleDbDataAdapter
Dim dt As DataTable
'cập nhật field Col1 về giá trị 4
Dim myOleDbCommand As New OleDbCommand("UPDATE Table1 SET Col1=4", CnnMain)
myOleDbCommand.ExecuteNonQuery()
'đọc lại field Col1 và hiển thị để kiểm tra
da = New OleDbDataAdapter("SELECT Col1 FROM Table1", CnnMain.ConnectionString)
dt = New DataTable
da.Fill(dt)
MsgBox(dt.Rows(0).Item("Col1"))
'Tại sao kết quả là 1234 mà không phải 4?
End Sub
End Class

" />
  • Thứ Ba, 24/05/2011 13:57 (GMT+7)

    Lập trình VB.NET, cập nhật database qua OleDb

    Câu hỏi :

    Dùng VB.NET, truy xuất database bằng các đối tượng OleDb, khi sử dụng lệnh truy vấn "Update" thì nhận thấy giá trị Update không kịp. Cụ thể tôi có 1 file database Access có tên là db1.mdb, bên trong database có 1 bảng dữ liệu tên là Table1, mỗi record của bảng Table1 có 1 field tên là Col1 thuộc kiểu số nguyên. Tôi viết 1 ứng dụng nhỏ gồm 1 form chứa 2 button: Khi click chuột vào Button2, chương trình sẽ cập nhật nội dung field Col1 (của tất cả record của bảng Table1) về giá trị 1234, còn khi click chuột vào Button1 thì chương trình sẽ cập nhật field Col1 (của tất cả record) về giá trị 4 rồi hiển thị giá trị vừa cập nhật để kiểm tra, nhưng thật bất ngờ kết quả hiển thị của field Col1 không bằng 4 mà bằng 1234. Như vậy lệnh Update chưa cập nhật kịp dữ liệu lên database. Xin hỏi nguyên nhân và cách khắc phục. Toàn bộ code VB .Net của ứng dụng như sau:

    'nhập cảng các class Oledb
    Imports System.Data.OleDb
    'đặc tả form ứng dụng
    Public Class Form1
    'định nghĩa các thuộc tính cần dùng
    Dim PathFileName As String = Application.StartupPath & "\db1.mdb"
    Dim CnnMain As OleDbConnection

    'thủ tục tạo kết nối đến database
    Sub Ketnoi_OleDb()
    CnnMain = New OleDbConnection
    CnnMain.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PathFileName & ";Persist Security Info=False"
    CnnMain.Open()
    End Sub

    'thủ tục khởi tạo form ứng dụng
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'tạo kết nối đến database
    Call Ketnoi_OleDb()
    End Sub

    'thủ tục xử lý click chuột trên Button2
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnGan.Click
    'cập nhật field Col1 về giá trị 1234
    Dim myOleDbCommand As New OleDbCommand("UPDATE Table1 SET Col1=1234", CnnMain)
    myOleDbCommand.ExecuteNonQuery()
    End Sub

    'thủ tục xử lý click chuột trên Button1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSuavaNhan.Click
    Dim da As OleDbDataAdapter
    Dim dt As DataTable
    'cập nhật field Col1 về giá trị 4
    Dim myOleDbCommand As New OleDbCommand("UPDATE Table1 SET Col1=4", CnnMain)
    myOleDbCommand.ExecuteNonQuery()
    'đọc lại field Col1 và hiển thị để kiểm tra
    da = New OleDbDataAdapter("SELECT Col1 FROM Table1", CnnMain.ConnectionString)
    dt = New DataTable
    da.Fill(dt)
    MsgBox(dt.Rows(0).Item("Col1"))
    'Tại sao kết quả là 1234 mà không phải 4?
    End Sub
    End Class



    Trả lời :

    Tình huống đọc nội dung field Col1 và hiển thị kết quả không theo ý muốn của bạn là do lỗi lập trình trong thủ tục xử lý click chuột Button1_Click. Thật vậy, bạn đã dùng biến CnnMain để miêu tả cầu nối đến database cần truy xuất, đã khởi tạo nó khi form bắt đầu chạy (trong hàm Form_Load). Lần đầu bạn click Button2 thì thủ tục Button2_Click chạy, nó cập nhật field Col1 của bảng Table1 thành 1234 rồi dừng ứng dụng, nội dung cập nhật được lưu lên file database. Lần chạy thứ hai, khi người dùng click Button1 thì thủ tục Button1_Click chạy, nó cập nhật field Col1 của bảng Table1 thành 4. Tuy nhiên, do cầu nối chưa được đóng nên các nội dung cập nhật vẫn còn nằm trong bộ đệm tạm (Cache) kết hợp với đối tượng CnnMain, chứ chưa được lưu thật sự lên file database (để đạt độ hiệu quả cao và khi cần dễ undo). Sau đó bạn tạo đối tượng OleDbDataAdapter để đọc bảng Table1 vào, tuy nhiên lệnh này dùng chuỗi ConnectionString để miêu tả database nên máy sẽ tạo 1 kết nối khác đến database (chứ không dùng kết nối do CnnMain quản lý), đọc dữ liệu hiện hành của bảng Table1 vào. Vì nội dung gốc của bảng Table1 trên file chưa bị cập nhật bởi lệnh Update nên khi máy hiển thị thì bạn vẫn thấy nó (1234). Bạn có thể dùng 1 trong 2 cách khắc phục lỗi trên như sau:

    - Cách 1: Thêm lệnh đóng cầu nối CnnMain sau khi đã thực hiện lệnh Update để máy ghi ngay kết quả lên file.
    Code của thủ tục Button1_Click sẽ như sau:
    'thủ tục xử lý click chuột trên Button1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSuavaNhan.Click
    Dim da As OleDbDataAdapter
    Dim dt As DataTable
    'cập nhật field Col1 về giá trị 4
    Dim myOleDbCommand As New OleDbCommand("UPDATE Table1 SET Col1=4", CnnMain)
    myOleDbCommand.ExecuteNonQuery()
    CnnMain.Close()
    'đọc lại field Col1 và hiển thị để kiểm tra
    da = New OleDbDataAdapter("SELECT Col1 FROM Table1", CnnMain.ConnectionString)
    dt = New DataTable
    da.Fill(dt)
    MsgBox(dt.Rows(0).Item("Col1"))
    'kết quả chắc chắn là 4.
    End Sub

    - Cách 2: Dùng tham số CnnMain thay vì dùng chuỗi ConnectionString trong lệnh tạo đối tượng OldDbdataApdater để đối tượng này dùng lại cầu nối cũ do CnnMain miêu tả, nhờ đó sẽ truy xuất được dữ liệu đã được cập nhật trước đó (mặc dù chúng chưa được ghi lên file database).
    Code của thủ tục Button1_Click sẽ như sau:
    'thủ tục xử lý click chuột trên Button1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSuavaNhan.Click
    Dim da As OleDbDataAdapter
    Dim dt As DataTable
    'cập nhật field Col1 về giá trị 4
    Dim myOleDbCommand As New OleDbCommand("UPDATE Table1 SET Col1=4", CnnMain)
    myOleDbCommand.ExecuteNonQuery()
    'đọc lại field Col1 và hiển thị để kiểm tra
    da = New OleDbDataAdapter("SELECT Col1 FROM Table1", CnnMain)
    dt = New DataTable
    da.Fill(dt)
    MsgBox(dt.Rows(0).Item("Col1"))
    'kết quả chắc chắn là 4.
    End Sub