Подтвердить что ты не робот

Как реализовать разбиение на страницы в SQL для MS Access?

Я получаю доступ к базе данных Microsoft Access 2002 (MDB) с использованием ASP.NET через класс OdbcConnection, который работает довольно хорошо, хотя и очень медленно.

Мой вопрос о том, как реализовать разбиение на страницы в SQL для запросов к этой базе данных, поскольку я знаю, что могу реализовать предложение TOP как:

SELECT TOP 15 *
FROM table

но я не могу найти способ ограничить это смещением, как это может быть сделано с SQL Server, используя ROWNUMBER. Моя лучшая попытка:

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

который терпит неудачу:

Источник ошибки: Microsoft JET Database Engine

Сообщение об ошибке: Нет значения для одного или нескольких требуемых параметров.

Я не могу решить эту ошибку, но я предполагаю, что она имеет какое-то отношение к подзапросу, который определяет rownumber?

Любая помощь будет оценена с этим; мои поиски в google дали бесполезные результаты: (

4b9b3361

Ответ 1

Если вы хотите применить пейджинг в MS Acces, используйте этот

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

Где 15 - StartPos + PageSize, а 5 - PageSize.

EDIT для комментариев:

Ошибка, которую вы получаете, заключается в том, что вы пытаетесь ссылаться на назначение имени столбца на том же уровне запроса, а именно на rownumber. Если вы хотите изменить свой запрос на:

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

Он не должен давать вам ошибку, но я не думаю, что это результат поискового вызова, который вы хотите.

Ответ 2

Обратите внимание на ответ на вопросник для исходного ответа, но здесь моя последняя реализация, которая учитывает некоторые правила парсера ODBC (для первых 15 записей после пропусков 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

Разница здесь в том, что мне нужно разбиение на страницы, чтобы работать при сортировке по имени клиента, и мне нужны все столбцы (ну, на самом деле это просто подмножество, но я сортирую это во внешнем запросе).

Ответ 3

Я использую этот код SQL для реализации разбивки на страницы с помощью 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

Я опубликовал статью с некоторыми скриншотами в моем блоге

Ответ 4

Один простой способ использовать ограничение или получить разбиение на страницы, работающие с доступом, - это использовать библиотеку ADODB, которая поддерживает разбиение на страницы для многих БД с одинаковым синтаксисом. http://phplens.com/lens/adodb/docs-adodb.htm#ex8 Его легко изменить/переопределить класс пейджера для извлечения требуемого количества строк в формате массива.

Ответ 5

Это простой способ разбиения на страницы с использованием классов OleDbDataAdapter и Datatable. Для простоты я использую другую команду SQL.

        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

Вот функция 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

Вышеуказанные коды возвратят 10 строк из таблицы Customer каждый раз, когда цикл будет работать до конца файла.