• Làm thế nào để dùng SQL trong lập trình?
  • RE: Làm thế nào để dùng SQL trong lập trình?

    paulsteigel > 10-05-16, 10:49 AM

    (10-05-16, 09:30 AM)Minh Tiên Đã viết: ....


    Bài này xứng đáng là một bài hay về cách tư duy với SQL...
    Do Tiên không gửi CSDL nên Ngọc làm tạm một bảng mô phỏng

    Bản chất của sự việc là bạn muốn đưa thông tin từ bảng tạm này vào bảng tblDanhsach_Hanghoa
    Vậy có 2 tình huống
    1. Có thể có các bản ghi trong tblDanhsach_Hanghoa rồi
    2. Chưa có - thì thêm vào

    Vậy giải pháp như sau:
    1. Liệt kê các bản ghi trong tblDanhsach_Hanghoa có mã hàng hóa trùng với Mahang trong strTableNameTam
    Cập nhập tblDanhsach_Hanghoa với giá trị mới với query UPDATE

    2. Liệt kê các bản trong strTableNameTam mà không có mã hàng hóa nào trùng với Mahang trong tblDanhsach_Hanghoa
    Thêm vào với INSERT INTO.

    Trong bài này có thêm khái niệm LEFT JOIN và INNER JOIN. Tôi sẽ giải thích sau.


    Mã:
    Sub UpdateHH()
        Dim SqlTxt As String
        ' Tat canh bao tu CSDL
        DoCmd.SetWarnings False
        
        ' Cap nhap nhung ma hang da co trong tblDanhsach_Hanghoa
        SqlTxt = "UPDATE tblDanhsach_Hanghoa AS d INNER JOIN ( " & _
            "SELECT b.Mahang, a.Dongianhap, a.Dongiabanle, a.Dongiabansy, [a].[Soluongton]+[b].[Soluongnhap] AS slTon " & _
            "FROM strTableNameTam AS b INNER JOIN tblDanhsach_Hanghoa AS a ON b.Mahang = a.Mahang) AS c " & _
            "ON d.Mahang = c.Mahang " & _
            "SET d.Soluongton = [c].[slTon], d.Dongianhap = [c].[Dongianhap], d.Dongiabanle = [c].[Dongiabanle], d.Dongiabansy = [c].[Dongiabansy];"
        ' O day co 2 Query, Query1_1 de lay danh sach nhung ban ghi co Mahang giong nhau giua tblDanhsach_Hanghoa strTableNameTam
        '   "SELECT b.Mahang, a.Dongianhap, a.Dongiabanle, a.Dongiabansy, [a].[Soluongton]+[b].[Soluongnhap] AS slTon " & _
        '   "FROM strTableNameTam AS b INNER JOIN tblDanhsach_Hanghoa AS a ON b.Mahang = a.Mahang
        ' Va Query 2 thuc hien viec UPDATE
        '   "UPDATE tblDanhsach_Hanghoa AS d INNER JOIN Query1_1 AS c " & _
        '    "ON d.Mahang = c.Mahang " & _
        '    "SET d.Soluongton = [c].[slTon], d.Dongianhap = [c].[Dongianhap], d.Dongiabanle = [c].[Dongiabanle], d.Dongiabansy = [c].[Dongiabansy];"
        
        ' Thuc thi lenh
        CurrentDb.Execute SqlTxt
        
        ' Them vao tblDanhsach_Hanghoa nhung cai khong co trong bang nay
        SqlTxt = "INSERT INTO tblDanhsach_Hanghoa ( Mahang, Tenhang, Donvitinh, Nhomhang, Nganhhang, Soluongton, Dongianhap, Dongiabanle, Dongiabansy ) " & _
            "SELECT a.Mahang, a.Tenhang, a.Donvitinh, a.Nhomhang, a.Nganhhang, a.Soluongnhap, a.Dongianhap, a.Dongiabanle, a.Dongiabansy " & _
            "FROM (SELECT c.Mahang, c.Tenhang, c.Donvitinh, c.Nhomhang, c.Nganhhang, c.Soluongnhap, c.Dongianhap, c.Dongiabanle, c.Dongiabansy " & _
            "FROM strTableNameTam AS c LEFT JOIN tblDanhsach_Hanghoa AS b ON c.Mahang = b.Mahang " & _
            "WHERE (((b.Mahang) Is Null))) AS a;"
        ' O day co 2 Query tuong tu nhu tren
        ' Querry1_2 xac dinh danh sach ban ghi trong strTableNameTam ma khong co trong tblDanhsach_Hanghoa
        '   "SELECT c.Mahang, c.Tenhang, c.Donvitinh, c.Nhomhang, c.Nganhhang, c.Soluongnhap, c.Dongianhap, c.Dongiabanle, c.Dongiabansy " & _
        '   "FROM strTableNameTam AS c LEFT JOIN tblDanhsach_Hanghoa AS b ON c.Mahang = b.Mahang " & _
        '   "WHERE (((b.Mahang) Is Null))
        
        ' Query thuc hien lenh chen ban ghi INSERT INTO (dat ten Query truoc la Querry1_2
        '   "INSERT INTO tblDanhsach_Hanghoa ( Mahang, Tenhang, Donvitinh, Nhomhang, Nganhhang, Soluongton, Dongianhap, Dongiabanle, Dongiabansy ) " & _
        '    "SELECT a.Mahang, a.Tenhang, a.Donvitinh, a.Nhomhang, a.Nganhhang, a.Soluongnhap, a.Dongianhap, a.Dongiabanle, a.Dongiabansy " & _
        '    "FROM Querry1_2 AS a;"
        CurrentDb.Execute SqlTxt
        DoCmd.SetWarnings True
    End Sub
  • RE: Làm thế nào để dùng SQL trong lập trình?

    paulsteigel > 10-05-16, 01:49 PM

    INNER JOIN - Kết hợp đồng dạng
    Một trong những câu lệnh truy vấn thông dụng và quan trọng nhất trong việc liên kết 2 bảng đó là INNER JOIN..
    Lệnh này giúp tạo ra bảng kết quả bằng cách kết hợp so sánh giá trị của 2 hoặc nhiều cặp cột của 2 bảng (ví dụ table1 và table 2) dựa trên chỉ dẫn cặp cột/ trường nào để so sánh giá trị. Truy vấn sẽ thực hiện so sánh mỗi dòng của bảng 1 với mỗi dòng của bảng 2 để tìm tất cả các cặp dòng của 2 bảng thỏa mãn chỉ dẫn so sánh. Khi thỏa mãn rồi, giá trị tìm được tương ứng của dòng A/B tìm thấy từ 2 bảng sẽ được trộn vào 1 bảng.
    Nói một cách nôm na là: Tìm kết quả sao cho giá trị của 2 cột so sánh là bằng nhau.
    Cú pháp

    Mã:
    SELECT table1.column1, table2.column2...
    FROM table1
    INNER JOIN table2
    ON table1.common_field = table2.common_field;


    Trong đó "ON table1.common_field = table2.common_field" là chỉ dẫn điều kiện so sánh

    SQL JOIN (LEFT/RIGHT...)- Kết hợp khác dạng

    INNER JOIN: Trả về tất cả các dòng phù hợp điều kiện cho trước từ 2 bảng
    LEFT JOIN: Trả về tất cả các dòng từ bảng bên trái và các dòng thỏa mãn điều kiện từ bảng bên phải
    RIGHT JOIN: Trả về tất cả các dòng từ bảng bên phải và các dòng thỏa mãn điều kiện ở bảng bên trái
  • RE: Làm thế nào để dùng SQL trong lập trình?

    Minh Tiên > 10-05-16, 04:08 PM

    Cảm ơn bạn Ngọc đã Hướng dẫn.
    Tiên vẫn chưa thử được SQL theo cách của bạn. Tiên nói rõ hơn thế này:

    1. tblDanhsach_Hanghoa được lưu trong 1 file da ta riêng mỗi lần thao tác thì kết nối qua ADODB.
    2. strTableNameTam được xây dựng trong CurrentProject.

    Khi thao tác xuất hàng hoặc nhập hàng thì làm trên strTableNameTam sau đó Update vào tblDanhsach_Hanghoa.

    Thanks!
  • RE: Làm thế nào để dùng SQL trong lập trình?

    paulsteigel > 10-05-16, 04:44 PM

    (10-05-16, 04:08 PM)Minh Tiên Đã viết: ....
    Với trường hợp của Tiên thì cách làm thế này nhé...
    1. Tạo ra một link từ CSDL hiện tại đến bảng tblDanhsach_Hanghoa trong CSDL tạm.
    2. Thực hiện đoạn code tôi đã post

    Vậy bổ sung đoạn code tạo link thế này nhé:
    1. Kiểm tra xem link tblDanhsach_Hanghoa có tồn tại không?
    2. Nếu có thì xem link này có tham chiếu đúng CSDL tạm không? Nếu không thì xóa đi.
    3. Nếu không thì tạo ra
    Kết thúc

    Và dưới đây là phần code dành cho Tiên

    Mã:
    Option Compare Database
    Option Explicit

    Sub UpdateHH()
        Dim SqlTxt As String, dbPath As String
        ' Tat canh bao tu CSDL
        DoCmd.SetWarnings False
        '========================================
        ' TIEN SUA DUONG DAN FILE DB TAM NHE...
        '========================================
        dbPath = "E:\Users\Paulsteigel\Desktop\GPE\QbNHNhan\tmpDb.mdb"
        '========================================
        If Not CreateLink("tblDanhsach_Hanghoa", dbPath, "tblDanhsach_Hanghoa") Then Exit Sub
        
        ' Cap nhap nhung ma hang da co trong tblDanhsach_Hanghoa
        SqlTxt = "UPDATE tblDanhsach_Hanghoa AS d INNER JOIN ( " & _
            "SELECT b.Mahang, a.Dongianhap, a.Dongiabanle, a.Dongiabansy, [a].[Soluongton]+[b].[Soluongnhap] AS slTon " & _
            "FROM strTableNameTam AS b INNER JOIN tblDanhsach_Hanghoa AS a ON b.Mahang = a.Mahang) AS c " & _
            "ON d.Mahang = c.Mahang " & _
            "SET d.Soluongton = [c].[slTon], d.Dongianhap = [c].[Dongianhap], d.Dongiabanle = [c].[Dongiabanle], d.Dongiabansy = [c].[Dongiabansy];"
        ' O day co 2 Query, Query1_1 de lay danh sach nhung ban ghi co Mahang giong nhau giua tblDanhsach_Hanghoa strTableNameTam
        '   "SELECT b.Mahang, a.Dongianhap, a.Dongiabanle, a.Dongiabansy, [a].[Soluongton]+[b].[Soluongnhap] AS slTon " & _
        '   "FROM strTableNameTam AS b INNER JOIN tblDanhsach_Hanghoa AS a ON b.Mahang = a.Mahang
        ' Va Query 2 thuc hien viec UPDATE
        '   "UPDATE tblDanhsach_Hanghoa AS d INNER JOIN Query1_1 AS c " & _
        '    "ON d.Mahang = c.Mahang " & _
        '    "SET d.Soluongton = [c].[slTon], d.Dongianhap = [c].[Dongianhap], d.Dongiabanle = [c].[Dongiabanle], d.Dongiabansy = [c].[Dongiabansy];"
        
        ' Thuc thi lenh
        CurrentDb.Execute SqlTxt
        
        ' Them vao tblDanhsach_Hanghoa nhung cai khong co trong bang nay
        SqlTxt = "INSERT INTO tblDanhsach_Hanghoa ( Mahang, Tenhang, Donvitinh, Nhomhang, Nganhhang, Soluongton, Dongianhap, Dongiabanle, Dongiabansy ) " & _
            "SELECT a.Mahang, a.Tenhang, a.Donvitinh, a.Nhomhang, a.Nganhhang, a.Soluongnhap, a.Dongianhap, a.Dongiabanle, a.Dongiabansy " & _
            "FROM (SELECT c.Mahang, c.Tenhang, c.Donvitinh, c.Nhomhang, c.Nganhhang, c.Soluongnhap, c.Dongianhap, c.Dongiabanle, c.Dongiabansy " & _
            "FROM strTableNameTam AS c LEFT JOIN tblDanhsach_Hanghoa AS b ON c.Mahang = b.Mahang " & _
            "WHERE (((b.Mahang) Is Null))) AS a;"
        ' O day co 2 Query tuong tu nhu tren
        ' Querry1_2 xac dinh danh sach ban ghi trong strTableNameTam ma khong co trong tblDanhsach_Hanghoa
        '   "SELECT c.Mahang, c.Tenhang, c.Donvitinh, c.Nhomhang, c.Nganhhang, c.Soluongnhap, c.Dongianhap, c.Dongiabanle, c.Dongiabansy " & _
        '   "FROM strTableNameTam AS c LEFT JOIN tblDanhsach_Hanghoa AS b ON c.Mahang = b.Mahang " & _
        '   "WHERE (((b.Mahang) Is Null))
        
        ' Query thuc hien lenh chen ban ghi INSERT INTO (dat ten Query truoc la Querry1_2
        '   "INSERT INTO tblDanhsach_Hanghoa ( Mahang, Tenhang, Donvitinh, Nhomhang, Nganhhang, Soluongton, Dongianhap, Dongiabanle, Dongiabansy ) " & _
        '    "SELECT a.Mahang, a.Tenhang, a.Donvitinh, a.Nhomhang, a.Nganhhang, a.Soluongnhap, a.Dongianhap, a.Dongiabanle, a.Dongiabansy " & _
        '    "FROM Querry1_2 AS a;"
        CurrentDb.Execute SqlTxt
        DoCmd.SetWarnings True
    End Sub

    Function CreateLink(strTable As String, strPath As String, strBaseTable As String) As Boolean
        On Error GoTo CreateAttachedError
        Dim tdf As TableDef
        Dim strConnect As String
        Dim fRetval As Boolean
        Dim myDB As Database
        
        ' Kiem tra xem bang co ton tai khong?
        If TableExists(strTable) Then CurrentDb.TableDefs.Delete strTable
        
        Set myDB = CurrentDb
        Set tdf = myDB.CreateTableDef(strTable)
        
        With tdf
            .Connect = ";DATABASE=" & strPath
            .SourceTableName = strBaseTable
        End With
        
        myDB.TableDefs.Append tdf
        
        fRetval = True
        
    CreateAttachedExit:
        CreateLink = fRetval
        Exit Function
        
    CreateAttachedError:
        If Err = 3110 Then
            Resume CreateAttachedExit
        Else
            If Err = 3011 Then
                Resume Next
            End If
        End If
    End Function

    Function TableExists(tblName As String) As Boolean
        On Error GoTo ErrHandler
        Dim tdf As TableDef
        Set tdf = CurrentDb.TableDefs(tblName)
        Set tdf = Nothing
        TableExists = True
    ErrHandler:
    End Function
  • RE: Làm thế nào để dùng SQL trong lập trình?

    Minh Tiên > 11-05-16, 09:08 AM

    Thanks Pau nhiều !
    Tiên đã test Update bằng SQL theo hướng dẫn của bạn. Kết quả: Update rất nhanh.
    Tiên đang kiểm tra lại thời gian Link table nữa. (Do mình chỉ mới Link thủ công để thử)
    Ngọc cho mình hỏi: Trong hàm CreatLink của bạn. Trường hợp link table có Pass thì cần sửa lại code như thế nào ?
    Cảm ơn nhiều !
  • RE: Làm thế nào để dùng SQL trong lập trình?

    Che_Guevara > 11-05-16, 09:40 AM

    Một chủ đề quá hay để học hỏi.
  • RE: Làm thế nào để dùng SQL trong lập trình?

    paulsteigel > 11-05-16, 09:48 AM

    (11-05-16, 09:08 AM)Minh Tiên Đã viết: ....

    Đây Tiên ơi,
    Bản chất của liên kết trong Access là một shortcut có thông tin để access kết nối CSDL. Nó chả khác giề ông DAO hoặc ADODB connection string.
    Giờ là lúc Tiên phải mày mò và tự đoán từ đoạn code sau của Ngọc nhé
    Mã:
    Function RemapLinks(Optional PwdString As String = "", Optional tPath As String = "") As DatabaseErrors
        ' Thực hiện việc tái lập liên kết bảng trong Access (với các Link đã có sẵn)
        Dim tdf As Object, tblName As String
        Err.Clear
        On Error GoTo ErrHandler
        For Each tdf In CurrentDb.TableDefs
            Debug.Print tdf.Name ' & " Type:" & tdf.Type
            If tdf.Connect <> "" Then
                tdf.Connect = "Ms Access;UID=Admin;PWD=" & PwdString & ";DATABASE=" & tPath
                tblName = tdf.Connect
                tdf.RefreshLink
            End If
        Next
        Set tdf = Nothing
        Exit Function
    ErrHandler:
        RemapLinks = Err.Number
        If Err.Number <> 0 Then WriteLog Err.Description
    End Function
  • RE: Làm thế nào để dùng SQL trong lập trình?

    Minh Tiên > 11-05-16, 03:17 PM

    Thanks Pau nhiều !
    Mình đã làm OK ! Nhanh hơn code cũ chuối của mình nhiều.
    Việc thực thi SQL rất OK.
    Tuy nhiên Tiên vẫn đang phân vân chưa lý giải được:

    1. Nếu chạy qua Lan mà Link table ở tất cả các PC qua 1 data thì có vấn đề gì ko ?
    2. Nếu như thế thì có cần thiết phải viết bằng ADODB để chạy Lan cho nhiều PC ko ?

    Nhờ Pau và các Pro chỉ giúp !
  • RE: Làm thế nào để dùng SQL trong lập trình?

    paulsteigel > 11-05-16, 03:34 PM

    (11-05-16, 03:17 PM)Minh Tiên Đã viết: ....

    Tiên cần mô hình hóa lên thì mình mới đáp lời được!
    Phần chạy trên các máy thì để ở các máy hay ở đâu?
    Data để ở máy chủ hay ở đâu
    File tạm để ở đâu?....
    Cái đó chắc Tiên biết rõ. Khi có đủ thông tin mình sẽ thưa thớt!
  • RE: Làm thế nào để dùng SQL trong lập trình?

    Minh Tiên > 11-05-16, 04:55 PM

    Thanks Pau !
    1. Da ta mình để trên 1 PC riêng (Chỉ phần table).
    2. Các PC (Dự kiến khoản 5 PC) khác mình dùng để chạy chương trình Bán hàng được Thiết kế gồm các đầy đủ các thành phần những table chỉ là các table tạm dùng để thao tác.
    Khi xuất hàng bán thì ghi các nội dung xuất trong table tạm, khi lưu --> Ghi và table ở da ta.
    3. À mình có đoạn code dùng SQL để Insert vào table (chỉ thêm mới):

    Mã:
    ...
    SqlTxt = "INSERT INTO tblNhaphang_Muavao_Chitiet (Stt,Mahang,Tenhang,Donvitinh,Nhomhang,Nganhhang,Soluongnhap,"
       SqlTxt = SqlTxt & "Dongianhap,Dongiabanle,Dongiabansy,Thanhtiennhap,Tienchietkhau,Hansudung,Ngaykiemke)"
       SqlTxt = SqlTxt & " SELECT Stt, Mahang,Tenhang,Donvitinh,Nhomhang,Nganhhang,Soluongnhap,Dongianhap,"
       SqlTxt = SqlTxt & "Dongiabanle,Dongiabansy,Thanhtiennhap,Tienchietkhau,Hansudung,Ngaykiemke FROM tblNhaphang_Muavao_Chitiet_Tam;"
       CurrentDb.Execute SqlTxt
    Không biết lỗi chỗ nào mà Insert ko được
    4. Mình muốn Insert thêm 1 Field vào tblNhaphang_Muavao_Chitiet mà không lấy từ tblNhaphang_Muavao_Chitiet_Tam mà lấy từ Form thì làm cách nào ?

    Rất mong Pau cùng các ACE Pro chỉ giúp !
    Cảm ơn nhiều !