2009-12-14 29 views
10

Tôi đang truy cập cơ sở dữ liệu Microsoft Access 2002 (MDB) bằng ASP.NET thông qua lớp OdbcConnection, hoạt động khá tốt mặc dù rất chậm.Làm cách nào để triển khai phân trang trong SQL cho MS Access?

Câu hỏi của tôi là về cách triển khai pagination trong SQL cho các truy vấn đến cơ sở dữ liệu này, như tôi biết tôi có thể thực hiện các khoản TOP như:

SELECT TOP 15 * 
FROM table 

nhưng tôi không thể tìm thấy một cách để hạn chế này để một bù đắp có thể được thực hiện với SQL Server bằng ROWNUMBER. nỗ lực tốt nhất của tôi là:

SELECT ClientCode, 
    (SELECT COUNT(c2.ClientCode) 
     FROM tblClient AS c2 
     WHERE c2.ClientCode <= c1.ClientCode) 
    AS rownumber 
FROM tblClient AS c1 
WHERE rownumber BETWEEN 0 AND 15 

mà không thành công với:

Lỗi Nguồn: Microsoft Cơ sở dữ liệu JET cơ

Thông báo lỗi: Không có giá trị nhất định cho một hoặc nhiều yêu cầu thông số.

Tôi không thể tìm ra lỗi này, nhưng tôi cho rằng nó có liên quan đến truy vấn phụ xác định rownumber?

Bất kỳ trợ giúp nào sẽ được đánh giá cao với điều này; tìm kiếm của tôi trên google đã mang lại kết quả vô ích :(

+0

Q này có 59 chế độ xem (tại thời điểm đó) và tôi không thấy một lần cập nhật nào. Đây có phải chỉ là một điều DBA? –

Trả lời

10

Nếu bạn muốn áp dụng phân trang trong MS Acces sử dụng này

SELECT * 
FROM (
    SELECT Top 5 sub.ClientCode 
    FROM (
     SELECT TOP 15 tblClient.ClientCode 
     FROM tblClient 
     ORDER BY tblClient.ClientCode 
    ) sub 
    ORDER BY sub.ClientCode DESC 
) subOrdered 
ORDER BY subOrdered.ClientCode 

đâu 15 là StartPos + PageSize, và 5 là PageSize.

EDIT nhận xét:

Các lỗi mà bạn nhận được, là bởi vì bạn đang cố gắng để tái ference một tên cột được gán cho cùng một cấp truy vấn, cụ thể là rownumber. Nếu bạn muốn thay đổi truy vấn của mình thành:

SELECT * 
FROM (
    SELECT ClientCode, 
      (SELECT COUNT(c2.ClientCode) 
      FROM tblClient AS c2 
      WHERE c2.ClientCode <= c1.ClientCode) AS rownumber     
    FROM tblClient AS c1 
) 
WHERE rownumber BETWEEN 0 AND 15 

Nó không cung cấp cho bạn lỗi, nhưng tôi không nghĩ rằng đây là kết quả phân trang bạn muốn.

+0

Cảm ơn! Mặc dù tôi đã nhận được một số vấn đề vẫn còn do ODBC SQL parser (xem câu trả lời của tôi). – Codesleuth

+0

Hãy xem câu trả lời đã chỉnh sửa. –

+1

Tất nhiên, có * đầu tát * Cũng có thể sử dụng mệnh đề HAVING mà tôi nghĩ, nhưng tôi không chắc chắn với JET - nó giống như cố gắng làm việc với SQL được bọc trong kính vỡ. – Codesleuth

3

Xem astander's answer cho câu trả lời ban đầu, nhưng đây là thực hiện cuối cùng của tôi mà sẽ đưa vào tài khoản một số quy tắc phân tích cú pháp ODBC (đối với 15 hồ sơ đầu tiên sau khi bỏ qua 30):

SELECT * 
FROM (
    SELECT Top 15 -- = PageSize 
    * 
    FROM 
    (
    SELECT TOP 45 -- = StartPos + PageSize 
    * 
    FROM tblClient 
    ORDER BY Client 
) AS sub1 
    ORDER BY sub1.Client DESC 
) AS clients 
ORDER BY Client 

Sự khác biệt ở đây là tôi cần phân trang để làm việc khi được sắp xếp theo tên khách hàng, và tôi cần tất cả các cột (tốt, thực sự chỉ là một tập hợp con, nhưng tôi sắp xếp ra trong truy vấn ngoài cùng).

1

tôi sử dụng mã SQL này để thực hiện các pagination với Access

Select TOP Row_Per_Page * From [
Select TOP (TotRows - ((Page_Number - 1) * Row_Per_Page)
From SampleTable Order By ColumnName DESC
] Order By ColumnName ASC

Tôi đã xuất bản một bài báo với một số ảnh chụp màn hình on my blog

0

Một cách dễ dàng để sử dụng giới hạn hoặc nhận được pagina tion làm việc trong truy cập là sử dụng thư viện ADODB hỗ trợ phân trang cho nhiều DB với cùng cú pháp. http://phplens.com/lens/adodb/docs-adodb.htm#ex8 Dễ dàng sửa đổi/ghi đè lớp máy nhắn tin của nó để tìm nạp số hàng yêu cầu theo định dạng mảng sau đó.

0

Đây là phương pháp phân trang đơn giản sử dụng các lớp OleDbDataAdapter và Datatable. Tôi đang sử dụng một lệnh SQL khác nhau để đơn giản.

 Dim sSQL As String = "select Name, Id from Customer order by Id" 
     Dim pageNumber As Integer = 1 
     Dim nTop As Integer = 20 
     Dim nSkip As Integer = 0 
     Dim bContinue As Boolean = True 
     Dim dtData as new Datatable 
     Do While bContinue 

      dtData = GetData(sSQL, nTop, nSkip, ConnectionString) 

      nSkip = pageNumber * nTop 
      pageNumber = pageNumber + 1 

      bContinue = dtData.Rows.Count > 0 
      If bContinue Then 
       For Each dr As DataRow In dtData.Rows 
        'do your work here 
       Next 
      End If 
     Loop 

Đây là chức năng GetData.

Private Function GetData(ByVal sql As String, ByVal RecordsToFetch As Integer, ByVal StartFrom As Integer, ByVal BackEndTableConnection As String) As DataTable 
    Dim dtResult As New DataTable 
    Try 
     Using conn As New OleDb.OleDbConnection(BackEndTableConnection) 
      conn.Open() 
      Using cmd As New OleDb.OleDbCommand 
       cmd.Connection = conn 
       cmd.CommandText = sql 
       Using da As New OleDb.OleDbDataAdapter(cmd) 
        If RecordsToFetch > 0 Then 
         da.Fill(StartFrom, RecordsToFetch, dtResult) 
        Else 
         da.Fill(dtResult) 
        End If 
       End Using 
      End Using 
     End Using 
    Catch ex As Exception 
    End Try 
    Return dtResult 
End Function 

Các mã trên sẽ trả về 10 hàng từ bảng Khách hàng mỗi lần vòng lặp hoạt động cho đến khi kết thúc tệp.

Các vấn đề liên quan