Chạy câu lệnh SQL và trả về kết quả bằng ADODB

Liên hệ QC

lehoctk

Thành viên chính thức
Tham gia
20/2/21
Bài viết
60
Được thích
1
Em chào cả nhà GPE, em đang gặp vấn đề về việc lấy dữ liệu từng dòng một và theo cột tùy ý từ bảng kết quả của Recordset (bảng recordset được lấy dữ liệu từ SQL bằng cách sử dụng ADODB.Command).
Hiện tại em chỉ có thể lấy dữ liệu tất cả bảng Recordset bằng thủ tục .CopyFromRecordset.
Vì dữ liệu lấy từ SQL nên em cũng không biết phải gửi file lên đây như thế nào, do đó em hy vọng nhà mình có thể giúp đỡ em câu lệnh mẫu ạ.
Em cảm ơn.
 
Em chào cả nhà GPE, em đang gặp vấn đề về việc lấy dữ liệu từng dòng một và theo cột tùy ý từ bảng kết quả của Recordset (bảng recordset được lấy dữ liệu từ SQL bằng cách sử dụng ADODB.Command).
Hiện tại em chỉ có thể lấy dữ liệu tất cả bảng Recordset bằng thủ tục .CopyFromRecordset.
Vì dữ liệu lấy từ SQL nên em cũng không biết phải gửi file lên đây như thế nào, do đó em hy vọng nhà mình có thể giúp đỡ em câu lệnh mẫu ạ.
Em cảm ơn.
Với rs là recordset mà bạn có được sau câu lênh truy vấn thì:
Rich (BB code):
Dim rs as Object, arrTemp

    arrTemp = rs.GetRows
    ReDim arrRsl(1 To UBound(arrTemp, 2) + 1, 1 To UBound(arrTemp, 1) + 1)
    For i = 0 To UBound(arrTemp, 2)
        For j = 0 To UBound(arrTemp, 1)
            arrRsl(i + 1, j + 1) = arrTemp(j, i)
        Next
    Next
Bạn xem cần lấy cột nào cho mảng kết quả arrRsl thì đặt điều kiện trong vòng lặp For j.
 
Upvote 0
Với rs là recordset mà bạn có được sau câu lênh truy vấn thì:
Rich (BB code):
Dim rs as Object, arrTemp

    arrTemp = rs.GetRows
    ReDim arrRsl(1 To UBound(arrTemp, 2) + 1, 1 To UBound(arrTemp, 1) + 1)
    For i = 0 To UBound(arrTemp, 2)
        For j = 0 To UBound(arrTemp, 1)
            arrRsl(i + 1, j + 1) = arrTemp(j, i)
        Next
    Next
Bạn xem cần lấy cột nào cho mảng kết quả arrRsl thì đặt điều kiện trong vòng lặp For j.
Cái này phải sửa câu lệnh SQL chứ sao lại ghi ra thế này.
 
Upvote 0
Cái này phải sửa câu lệnh SQL chứ sao lại ghi ra thế này.
Không biết thớt truy vấn như thế nào nhưng chỉ biết là thớt lấy được recordset thì chừ muốn chọn để lấy từng cột thì phải làm thế này chứ sao nữa bạn. --=0
 
Upvote 0
Em xin cảm ơn mọi người đã trợ giúp ạ.
 
Upvote 0
Em chào cả nhà GPE, em đang gặp vấn đề về việc lấy dữ liệu từng dòng một và theo cột tùy ý từ bảng kết quả của Recordset (bảng recordset được lấy dữ liệu từ SQL bằng cách sử dụng ADODB.Command).
Hiện tại em chỉ có thể lấy dữ liệu tất cả bảng Recordset bằng thủ tục .CopyFromRecordset.
Vì dữ liệu lấy từ SQL nên em cũng không biết phải gửi file lên đây như thế nào, do đó em hy vọng nhà mình có thể giúp đỡ em câu lệnh mẫu ạ.
Em cảm ơn.
Nguyên tắc là luôn giảm thiểu việc tải dữ liệu qua mạng, ảnh hưởng băng thông, tốc độ thực hiện. Do đó, tôi luôn chỉ lấy về dữ liệu cần thiết, không lấy dư thừa, nguyên cả table, cái nào thực hiện được ngay trên Server thì xử lý trên đó, chỉ lấy về kết quả. Chỉ khi nguyên table đó còn có thể tái sử dụng tất cả các field trong đó thì mới tải cả table.
Còn việc lọc dữ liệu theo dòng thì dùng phương thức Recordset.Filter nhé.
 
Lần chỉnh sửa cuối:
Upvote 0
Còn việc lọc dữ liệu theo dòng thì dùng phương thức Recordset.Filter nhé.
Lấy theo cột thì tôi thường Select từng cột chứ không Select *, thậm chí thêm trường tính toán, trường constant trong phần Select.
Còn lọc theo dòng thì tôi tưởng là nên dùng Where trong câu SQL chứ?
 
Upvote 0
Lấy theo cột thì tôi thường Select từng cột chứ không Select *, thậm chí thêm trường tính toán, trường constant trong phần Select.
Còn lọc theo dòng thì tôi tưởng là nên dùng Where trong câu SQL chứ?
Where cũng được anh, tuỳ trường hợp mà dùng thôi. Dùng Filter khi có nhu cầu trả về số record ban đầu. Ví dụ như dùng trong các Form tìm kiếm, tìm xong thì bấm Show all để hiển thị tất cả.
 
Upvote 0
Lấy theo cột thì tôi thường Select từng cột chứ không Select *, thậm chí thêm trường tính toán, trường constant trong phần Select.
Còn lọc theo dòng thì tôi tưởng là nên dùng Where trong câu SQL chứ?
Dạ, do Dữ liệu này em gọi từ thủ tục có sẵn của Data từ phần mềm kế toán bác ạ. thủ tục đã Select nhiều cột rồi nên em không thể sửa, nếu sửa sẽ làm sai lệch kết quả khi sử dụng phần mềm ạ.
 
Upvote 0
Với rs là recordset mà bạn có được sau câu lênh truy vấn thì:
Rich (BB code):
Dim rs as Object, arrTemp

    arrTemp = rs.GetRows
    ReDim arrRsl(1 To UBound(arrTemp, 2) + 1, 1 To UBound(arrTemp, 1) + 1)
    For i = 0 To UBound(arrTemp, 2)
        For j = 0 To UBound(arrTemp, 1)
            arrRsl(i + 1, j + 1) = arrTemp(j, i)
        Next
    Next
Bạn xem cần lấy cột nào cho mảng kết quả arrRsl thì đặt điều kiện trong vòng lặp For j.
Bác ơi, bác cho em hỏi em gán arrTemp bị lỗi: Run-time error '3021': Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record" là sao vậy bác?
Em check thì giá trị BOF = False và EOF = True ạ
 
Upvote 0
Bác ơi, bác cho em hỏi em gán arrTemp bị lỗi: Run-time error '3021': Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record" là sao vậy bác?
Em check thì giá trị BOF = False và EOF = True ạ
Bạn xem cái rs đó tương đương với biến nào của bạn chứ hình như bạn dùng rs mới khai báo thì phải
 
Upvote 0
Em đã khai báo và Set value rồi, em thử Copy rs vào bảng bằng phương thức .CopyFromRecordset thì có dữ liệu mà bác
Bạn phải thiết lập con trỏ lúc truy vấn dữ liệu. Đâu bạn gửi cái code của bạn xem thử nhé.
 
Upvote 0
Em đã khai báo và Set value rồi, em thử Copy rs vào bảng bằng phương thức .CopyFromRecordset thì có dữ liệu mà bác
À, theo như bạn mô tả và đọc bài 13 thì tôi nhớ ra rồi. Vì bạn đã copy rồi nên con trỏ đang ở cuối recordset. Giờ bạn thử chèn câu lệnh rs.MoveFirst trước rs.GetRows xem.
 
Upvote 0
Nguyên tắc là luôn giảm thiểu việc tải dữ liệu qua mạng, ảnh hưởng băng thông, tốc độ thực hiện. Do đó, tôi luôn chỉ lấy về dữ liệu cần thiết, không lấy dư thừa, nguyên cả table, cái nào thực hiện được ngay trên Server thì xử lý trên đó, chỉ lấy về kết quả. Chỉ khi nguyên table đó còn có thể tái sử dụng tất cả các field trong đó thì mới tải cả table.
Còn việc lọc dữ liệu theo dòng thì dùng phương thức Recordset.Filter nhé.
Như thớt giải thích ở bài #9, đây là gọi từ một cái SP (stored procedure). Nó cho ra gì lấy nấy. Chỉ cần biết là nó có cho đúng con số cẩn thiết thôi.

Tuy nhiên, theo nguyên tắc kết nối với Database Server thì Db Manager họ cũng cần tiết kiệm băng thông, đường nối, vv... Vì vậy, chỉ cần trình bày rõ vấn đề thì họ sẵn sàng viết cái SP khác cho.
Viết một cái SP nhanh và dễ hơn viết code VBA nhiều. Nếu mình biết cách nói chuyện thì họ sẽ vui vẻ. (Rất tiếc là hầu hết bà con ở đây đi làm việc mà không hề luyện qua kỹ năng giao tiếp)

Trừ hai trường hợp đặc biệt:
1. Db Manager lỡ sắm cái hệ thống lớn quá, khi kiểm tra họ thấy chạy dưới 40% công suất thì họ sẽ trừ điểm KPI. Người Db Manager bắt buộc phải tìm những chỗ tiêu thụ cho hết tiềm năng máy (trên 60%). Trên nguyên tắc, KPIs dùng để báo động những chỗ chưa hiệu quả. Nhưng ở VN người ta áp dụng KPIs như cái roi đe con bò phải kéo xe cật lực.
2. Tương tự như trên, nhưng ở tình huống ngược lại. Hệ thống chạy gần đến 80-90% công suất rồi. Người Db Manager muốn tìm cách cho nó sát 100% hơn để có cớ xin sắm hệ thống mới, giựt le với đào.

@thớt:
Lỡ có cái recordset rồi thì cứ việc chép ra sheet (nếu cần thì sheet tạm cũng được). Rồi sau đó dùng code filter, xóa cột,... Hoặc lại dùng ADODB lấy cột, lọc dòng. Làm vậy dễ kiểm soát dữ liệu hơn.
 
Upvote 0
Bạn phải thiết lập con trỏ lúc truy vấn dữ liệu. Đâu bạn gửi cái code của bạn xem thử nhé.
Em ơn bác, em tìm ra nguyên nhân lỗi và khắc phục được rồi ạ.
Bài đã được tự động gộp:

Như thớt giải thích ở bài #9, đây là gọi từ một cái SP (stored procedure). Nó cho ra gì lấy nấy. Chỉ cần biết là nó có cho đúng con số cẩn thiết thôi.

Tuy nhiên, theo nguyên tắc kết nối với Database Server thì Db Manager họ cũng cần tiết kiệm băng thông, đường nối, vv... Vì vậy, chỉ cần trình bày rõ vấn đề thì họ sẵn sàng viết cái SP khác cho.
Viết một cái SP nhanh và dễ hơn viết code VBA nhiều. Nếu mình biết cách nói chuyện thì họ sẽ vui vẻ. (Rất tiếc là hầu hết bà con ở đây đi làm việc mà không hề luyện qua kỹ năng giao tiếp)

Trừ hai trường hợp đặc biệt:
1. Db Manager lỡ sắm cái hệ thống lớn quá, khi kiểm tra họ thấy chạy dưới 40% công suất thì họ sẽ trừ điểm KPI. Người Db Manager bắt buộc phải tìm những chỗ tiêu thụ cho hết tiềm năng máy (trên 60%). Trên nguyên tắc, KPIs dùng để báo động những chỗ chưa hiệu quả. Nhưng ở VN người ta áp dụng KPIs như cái roi đe con bò phải kéo xe cật lực.
2. Tương tự như trên, nhưng ở tình huống ngược lại. Hệ thống chạy gần đến 80-90% công suất rồi. Người Db Manager muốn tìm cách cho nó sát 100% hơn để có cớ xin sắm hệ thống mới, giựt le với đào.

@thớt:
Lỡ có cái recordset rồi thì cứ việc chép ra sheet (nếu cần thì sheet tạm cũng được). Rồi sau đó dùng code filter, xóa cột,... Hoặc lại dùng ADODB lấy cột, lọc dòng. Làm vậy dễ kiểm soát dữ liệu hơn.
Cảm ơn bác nhưng em xin thông tin thêm tới bác về vấn đề của em tại sao lại bắt buộc dùng VBA để đọc dữ liệu từ SP mà không tùy biến lại SP, hoặc viết thêm SP (do viết thêm SP từ VBA không tiện, mà viết SP từ SQL thì người dùng phổ thông sẽ không biết cách làm nếu trong tương lai tạo thêm DATABASE).
Bởi vì em đang sử dụng phần mềm kế toán MISA (là phần mềm đóng gói sẵn, và SP trả về bảng dữ liệu có nhiều cột là vì phần mềm cần sử dụng tới nên không được phép sửa SP, nếu sửa sẽ dẫn tới lỗi PM), tuy nhiên cũng chính vì là phần mềm đóng gói sẵn nên có những tính năng thừa với nhu cầu của mình trong khi một số khác lại chưa đáp ứng được. Do đó em mới cố gắng sử dụng dữ liệu SQL và để tùy biến báo cáo theo nhu cầu riêng của mình.
Cảm ơn bác, và các thành viên khác trên GPE đã giúp đỡ và em đã sửa được lỗi và hoàn thành yêu cầu của mình ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
Có vẻ như thớt không biết cái SP mà tôi nói ở bài #15.
Tôi xin nhận sai và rút lại những lời nói về SQL Server ở bài ấy.
Vấn đề của thớt nằm ngoái khả năng tôi.
 
Upvote 0
Có vẻ như thớt không biết cái SP mà tôi nói ở bài #15.
Tôi xin nhận sai và rút lại những lời nói về SQL Server ở bài ấy.
Vấn đề của thớt nằm ngoái khả năng tôi.
Cảm ơn bác ạ, bác khiêm tốn rồi, chắc do em mô tả vấn đề chưa được rõ ràng thôi ạ. Ý em nói tới ở bài #16 là trường hợp người dùng khác không biết cách tạo SP khi họ tạo mới CSDL, hoặc trường hợp họ không được cấp quyền tạo SP, còn đọc SP có sẵn từ CSDL thì được, nên em mới chấp nhận tốn băng thông, đường nối,... như bác nói để sử dụng VBA ạ. Với thực tế CSDL của em không bao giờ quá lớn ạ.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom