2015-04-10 15 views
9

So che la versione è troppo vecchia (sì versione 4!), Ma non ho scelta.Limite query SQL per DB2 AS/400 Versione 4

Come limitare la mia query ad esempio 100 righe solo per DB2 AS400?

FETCH FIRST n ROWS ONLY 

e

ROW_NUMBER() 

non funzionano.

Qualsiasi idea o soluzione alternativa?

Ecco una query di esempio SQL (non funziona):

SELECT POLNOP FROM ZICACPTF.POLHDR FETCH FIRST 10 ROWS ONLY 

Si dice

[SQL0199] Chiave non FETCH previsto. Token validi: PER CON L'UNIONE DELL'ORDINE OTTIMIZZARE.

+1

Il primo riferimento trovato per _fetch-first-clause_ è V5R1, analogamente per 'ROW_NUMBER()'. Puoi dare un esempio di ** come ** vuoi usarlo? Un'istruzione FETCH può recuperare un blocco di, ad esempio, 100 righe. È possibile FETCH una volta ed elaborare solo quelle righe, ma ciò implica SQL incorporato. Inoltre, c'erano cinque versioni separate di 'versione 4' - qual è il tuo? – user2338816

+0

V4R4, cosa ho solo quello che è per recuperare una tabella, ma limitato per esempio solo 10 righe. in mysql è come 'select * from table1 limit 10' – Kevin

+1

Stai utilizzando una versione MySQL del 2001? Questo è (apparentemente) quando la _fetch-first-clause_ appare in DB2 su iSeries, quindi un confronto simile dovrebbe essere fatto per MySQL. Non si può fare molto sulla V4R4 che ora ha più di 15 anni. IMO, l'unica possibilità ragionevole è l'SQL incorporato in cui FETCH le prime 10 righe. Non riesco a ricordare i requisiti per gli stored process SQL memorizzati su V4R4. Potresti crearne uno che restituisca un set di risultati contenente solo 10 righe. Se un proc SQL memorizzato non è ragionevole, è possibile utilizzare un proc memorizzato esterno. – user2338816

risposta

2

C'è nessun supporto dbms per questa operazione, controllare Version 4 DB2 UDB for AS/400 SQL Reference: No Limit, Top, First, ... parole riservate.

È possibile provare a limitare le righe tramite la clausola where, where sequence between 100 and 200. Ma questo è uno scenario irreale.

primo lavoro intorno è tramite cursore:

DECLARE ITERROWS INTEGER; 
... 
SET ITERROWS = 0; 
DO WHILE (SUBSTR(SQLSTATE,1,2) = '00' and ITERROWS < 100 
DO 
    ... 
    SET ITERROWS = ITERROWS + 1; 

seconda, nella tua lingua middleware.

Spero che qualcuno post una soluzione intelligente, ma, a mio parere, non lo sono.

+0

Grazie, sembra che non ci sia davvero modo di usare la clausola LIMIT come per V4R4. Tristemente, sto usando Java + Hibernate e non possiamo cambiare (ancora) qualcosa all'interno di AS400 – Kevin

+0

Hibernate non è in grado di gestire il tuo problema tramite [Query.setMaxResults()] (http://stackoverflow.com/a/ 1239745)? (disclaimer, non testato) – danihp

+0

sì, utilizza V5, FETCH FIRST [n] ROWS ONLY clausola – Kevin

0

soluzione solo per> V4R4

Utilizzando FETCH FIRST [n] ROWS ONLY:

SELECT LASTNAME, FIRSTNAME, EMPNO, SALARY 
    FROM EMP 
    ORDER BY SALARY DESC 
    FETCH FIRST 10 ROWS ONLY; 

Riferimento: publib.boulder.ibm.com

La differenza che posso vedere dalla I dati di questo esempio è che qui siamo usando una clausola ORDER BY - hai la possibilità di aggiungere un ORDER BY - dovrebbe fare il trucco. Riferimento a: https://stackoverflow.com/a/16858430/1581725


Per ottenere intervalli o anche solo le prime 10 righe, che avrebbe dovuto usare ROW_NUMBER() (dal V5R4):

SELECT 
    * 
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY {{table field}}) AS ROWNUM, * {{yourtable}} 
) AS {{yourcursor}} 
WHERE 
    {{yourcursor}}.ROWNUM>0 AND 
    {{yourcursor}}.ROWNUM<=10 

Riferimento: blog.zanclus.com

+0

questo non funziona in V4R4 :) – Kevin

+1

Aveva solo una v5r4 - non volevo lasciarti senza soluzione. Aggiungerò questo in prima linea - forse qualcuno ha bisogno di questo per le versioni successive. Grazie per il tuo feedback @Kevin – DominikAngerer