-
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
-
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):
Không biết lỗi chỗ nào mà Insert ko đượcMã:...
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
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 !