Domanda

Come eseguire il paging in Pervasive SQL (versione 9.1)? Devo fare qualcosa di simile come:

//MySQL
SELECT foo FROM table LIMIT 10, 10

Ma non riesco a trovare un modo per definire l'offset.

È stato utile?

Soluzione 4

Ho finito per fare il paging nel codice. Salto i primi dischi in loop.

Pensavo di aver inventato un modo semplice per eseguire il paging, ma sembra che sql pervasivo non consenta clausole d'ordine nelle sottoquery. Ma questo dovrebbe funzionare su altri DB (l'ho testato su Firebird)

select *
from (select top [rows] * from
(select top [rows * pagenumber] * from mytable order by id)
order by id desc)
order by id

Altri suggerimenti

Query testata in PSQL:

select top n * 
from tablename 
where id not in(
select top k id
from tablename 
) 

per tutti i n = no. di record che devi recuperare alla volta. e k = multipli di n (es. n = 5; k = 0,5,10,15, ....)

Il nostro paging ha richiesto la possibilità di passare il numero di pagina corrente e le dimensioni della pagina (insieme ad alcuni parametri di filtro aggiuntivi) come variabili. Poiché un @page_size top selezionato non funziona in MS SQL, abbiamo creato una tabella temporanea o variabile per assegnare a ciascuna chiave primaria di righe un'identità che può essere successivamente filtrata in base al numero e alla dimensione di pagina desiderati.

** Si noti che se si dispone di una chiave primaria GUID o di una chiave composta, è sufficiente modificare l'ID oggetto nella tabella temporanea in un identificativo univoco o aggiungere le colonne chiave aggiuntive alla tabella.

Il lato negativo di questo è che deve ancora inserire tutti i risultati nella tabella temporanea, ma almeno sono solo le chiavi. Funziona in MS SQL, ma dovrebbe essere in grado di funzionare per qualsiasi DB con modifiche minime.

  

dichiara @page_number int, @page_size   int - aggiunge qualsiasi ricerca aggiuntiva   parametri qui

     

: crea la tabella temporanea con la colonna Identity e l'id
  - del record che selezionerai. Questo è un ricordo
  --table, quindi se il numero di righe che inserirai è maggiore
  - 10.000, quindi dovresti usare una tabella temporanea in tempdb
  --anziché. Per fare questo, usa
  --CREATE TABLE #temp_table (row_num int IDENTITY (1,1), objectid int)
  --e modifica tutti i riferimenti in @temp_table in #temp_table
  DECLARE @temp_table TABLE (row_num int   IDENTITÀ (1,1), objectid int)

     

- inserire nella tabella temporanea con gli ID dei record
  - vogliamo tornare. È fondamentale assicurarsi l'ordine da parte di
  - riflette l'ordine dei record da restituire in modo che row_num
  - I valori sono impostati nell'ordine corretto e stiamo selezionando la
  - record corretti basati sulla pagina
INSERT INTO @temp_table   (ObjectID)

     

/ * Esempio: selezionare gli inserti   record nella tabella temporanea
  SELEZIONA personid
DA persona CON   (NOLOCK)
diploma interno interno CON   (NOLOCK) su degree.personid =   person.personid
DOVE   person.lastname = @last_name
  ORDINA PER person.lastname asc,   person.firsname asc
  * /

     

: indica il numero totale di righe corrispondenti a DECLARE @total_rows   int
SET @total_rows =   @@ ROWCOUNT
  - Calcola il numero totale di pagine in base al numero di
  --row corrisponde e le dimensioni della pagina passano come parametro
DECLARE   @total_pages int
  --aggiunge @page_size - 1 al numero totale di righe da
  - Calcola il numero totale di pagine. Questo perché sql
  --alwasy arrotonda per difetto alla divisione di numeri interi
SET @total_pages =   (@total_rows + @page_size - 1) /   @page_size

     

: restituisci il set di risultati a cui siamo interessati aderendo a
  - torna a @temp_table e filtro per row_num
/ * Esempio:   Selezione dei dati da restituire. Se la   l'inserimento è stato eseguito correttamente, quindi   dovresti sempre unirti al tavolo   che contiene le righe da restituire   alla colonna objectid su   @temp_table

     

SELEZIONA persona. *
DA persona CON   (NOLOCK) INNER JOIN @temp_table   tt
ON person.personid =   tt.objectid
  * /
  - Restituisci solo le righe della pagina che ci interessano
  --e ordina per la colonna row_num di @temp_table per assicurarti che
  - stiamo selezionando i record corretti
DOVE tt.row_num <   (@page_size * @page_number) + 1
  AND tt.row_num & Gt; (@dimensioni della pagina *   @page_number) - @page_size
ORDINA   BY tt.row_num

Ho riscontrato questo problema anche in MS SQL ... nessuna funzione Limit o rownumber. Quello che faccio è inserire le chiavi per il risultato della mia query finale (o talvolta l'intero elenco di campi) in una tabella temporanea con una colonna di identità ... quindi elimino dalla tabella temporanea tutto al di fuori dell'intervallo che voglio ... quindi uso un join contro le chiavi e la tabella originale, per riportare gli oggetti che desidero. Funziona se hai una bella chiave unica - se non lo fai, beh ... questo è un problema di progettazione in sé.

Un'alternativa con prestazioni leggermente migliori è saltare la fase di eliminazione e usare semplicemente i numeri di riga nell'unione finale. Un altro miglioramento delle prestazioni consiste nell'utilizzare l'operatore TOP in modo che, per lo meno, non sia necessario afferrare le cose oltre la fine di ciò che si desidera.

Quindi ... in pseudo-codice ... per afferrare gli oggetti 80-89 ...

create table #keys (rownum int identity(1,1), key varchar(10))

insert #keys (key)
select TOP 89 key from myTable ORDER BY whatever

delete #keys where rownumber < 80

select <columns> from #keys join myTable on #keys.key = myTable.key
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top