Table of Contents
- STRSQL
- Istruzione SELECT
- Limitare il numero di record restituiti
- Count() e Distinct
- Alias su nomi di campi (Operatore AS per intestazioni di campo)
- JOIN di file
- INNER JOIN
- LEFT JOIN
- RIGHT JOIN
- Alias su file (Operatore AS)
- Operatore GROUP BY e funzioni di aggregazione
- Operatore WHERE
- Operatore LIKE
- Operatore BETWEEN
- Operatore IN / NOT IN
- Operatore EXISTS / NOT EXISTS
- Instruzione INSERT
- Istruzione UPDATE
- Istruzione DELETE
- Gestione file multimembro
- Esportazione dei risultati di una query in un file
- Creazione di viste logiche
- Operazioni sulle stringhe
- Funzione SUBSTR
- Funzione CONCAT
- Trasformazione MAIUSCOLE/minuscole
- Rimozione degli spazi (TRIM / LTRIM / RTRIM)
- Campi stringa contenenti un valore con l'apice
- Operazioni sui numerici
- Conversione di numeri in stringhe_n_
- Arrotondamenti con SQL_n_
- Divisione e problemi con gli Integer_n_
- Operazioni sulle date
- Funzione RRN()
- Campi condizionati: CASE, WHEN, ELSE, END
- File di sistema
- Utilizzo di un cursore per la lettura di dati in SQLRPGLE
- Serial cursor
- Declare
- Prepare
- Open
- Fetch
- Close
- Scrollable cursor
- Declare
- Prepare
- Open
- Fetch
- Close
- Accorgimenti relativi alle performance
- File fisici e logici
STRSQL
Per eseguire una query SQL su A/400, richiamare da linea comandi:
STRSQL
Istruzione SELECT
L'istruzione SELECT consente la selezione dei campi che si desidera visualizzare di uno o più file.Sintassi:
SELECT *|nomecampo, nomecampo,... FROM file
Dopo l'operatore SELECT vengono indicati i campi da visualizzare, mentre dopo l'operatore FROM i file da cui recuperare i dati.
Per la selezione di tutti i campi di un file si utilizza la parola chiave *. Es.:
SELECT * FROM BRENTI0F
Esegue la selezione di tutti i campi del file dell'anagrafica enti.
In alternativa, è possibile specificare il nome dei campi da visualizzare separati da virgola. Es.:
SELECT E§TRAG, E§CRAG FROM BRENTI0F
Esegue la selezione dei campi tipo e codice del file dell'anagrafica enti.
Limitare il numero di record restituiti
FETCH FIRST _i_ n _n_ ROW ONLY
n indica il numero di record da restituire
SELECT * FROM BRENTI0F
WHERE E§TRAG = 'COL'
ORDER BY E§RAGS
FETCH FIRST 10 ROW ONLY
Seleziona i primi 10 collaboratori in ordine di ragione sociale dall'anagrafica enti.
Count() e Distinct
Vediamo l'utilizzo della funzione COUNT per contare il numero di record selezionati:
SELECT cdnaz, COUNT(cdnaz) FROM Clienti GROUP BY Cdnaz
In questo caso vengono ritornati il codice nazione e il numero di clienti della stessa nazione.
La parola chiave DISTINCT esclude i risultati duplicati della SELECT-
Se volessimo sapere quante nazioni diverse abbiamo nel file clienti:
SELECT COUNT(DISTINCT(Cdnaz)) FROM Clienti
Un altro metodo è:
SELECT COUNT(*) FROM (SELECT DISTINCT(Cdnaz, Cdpag) FROM Clienti) as PIPPO
Attenzione: questa istruzione funziona solo dalla versione V4R4 in avanti.
Alias su nomi di campi (Operatore AS per intestazioni di campo)
Quando si esegue una select a video, le intestazioni delle colonne sono le descrizioni COLHDG dei campi del file.Nel caso non sia presente COLHDG, viene usato il nome del campo. E' possibile visualizzare un'intestazione a piacere, utilizzando la parola chiave AS:
SELECT Codcli AS "Codice Cliente" FROM Clienti ....
Per cose più complesse è possibile ricorrere al Query Manager STRQM, con il quale è possibile separare la parte SQL da quella di output.
JOIN di file
Un'operazione di JOIN consente la selezione di record in due tabelle collegate.Si distinguono 3 tipi di JOIN:
INNER JOIN
L'INNER JOIN consente la selezione dei soli record che hanno una corrispondenza in entrambi i file specificati.Es.: Se voglio fare una join su record dello stesso file si possono utilizzare gli alias:
SELECT * FROM C5TREG0F AS T1, C5TREG0F AS T2 WHERE T1.T5PROG=T2.T5PROG
L'istruzione sopra specificata è equivalente a:
SELECT * FROM C5TREG0F AS T1
INNER JOIN C5TREG0F AS T2
ON T1.T5PROG=T2.T5PROG
La parola chiave INNER può anche essere omessa:
SELECT * FROM C5TREG0F AS T1
JOIN C5TREG0F AS T2
ON T1.T5PROG=T2.T5PROG
LEFT JOIN
Il LEFT JOIN consente la selezione di tutti i record del primo file e di quelli corrispondenti nel secondo.È anche possibile utilizzare il LEFT JOIN per farsi restituire i record non corrispondenti con una condizione nella WHERE in cui il campo su cui si esegue il join sia NULL.
Es.:
SELECT ATTROBJECTS.OBJATTRDESCRIPTION,OBJTYPE, DOCUMENTS.*
FROM ATTROBJECTS
LEFT JOIN DOCUMENTS
ON ATTROBJECTS.OBJCODE=DOCUMENTS.OBJCODE
WHERE DOCUMENTS.OBJCODE IS NULL
RIGHT JOIN
Il RIGHT JOIN consente la selezione di tutti i record del secondo file e di quelli corrispondenti nel primo. Alias su file (Operatore AS)
NELLE JOIN FRA FILE CON GLI STESSI CAMPI VA SEMPRE MESSO 'AS' SU TUTTII FILE ALTRIMENTI SI HANNO COMPORTAMENTI ANOMALI ANCHE NON SEGNALATI.
(Es.: una Where EXISTS fatta su un file ridenominato e l'altro no ha sempre risultati positivi).
Operatore GROUP BY e funzioni di aggregazione
L'operatore GROUP BY consente l'aggregazione di record raggruppati in base all'elenco dei campi specificati.
SELECT E§TRAG, E§CRAG, E§RAGS FROM BRENTI0F
GROUP BY E§TRAG, E§CRAG, E§RAGS
Seleziona i record dell'anagrafica enti raggruppandoli per tipo, codice, ragione sociale.
L'utilizzo del GROUP BY è associato a quello di funzioni di aggregazione (ad esempio COUNT() per il conteggio, AVG() per eseguire la media su un campo, SUM() per sommare i valori di un campo, MAX() e MIN() per farsi restituire rispettivamente il valore massimo e minimo, ecc...)
Se da un file statistico, ad esempio le righe di vendita, si volessero ottenere i subtotali per nazione e quindi il totale generale come con Query/400:
SELECT NAZI, COUNT(*), SUM(FATT) FROM STATIS0F
GROUP BY NAZI
UNION ALL
SELECT '999 TOTALE', COUNT(*), SUM(FATT)
FROM STATIS0F GROUP BY '999 TOTALE'
ORDER BY 1
Si supponga di avere una tabella con lo storico delle vendite degli ultimi n anni, in cui ogni record rappresenta una riga di bolla/fattura con cliente, articolo, quantità, data consegna, ecc... e si desidera calcolare la media (anno x anno) delle righe consegnate per ogni giorno:
SELECT ANNO, AVG(COUNTGIO) AS MEDIAANNO
FROM (Select substring(char(DATACONS),1, 4) as ANNO, DATACONS, COUNT(*) as COUNTGIO
from STORICO group by substring(char(DATACONS),1, 4), DATACONS) as storico group by ANNO order by ANNO
Correlato all'operatore GROUP BY, vi è l'operatore HAVING, che consente di filtrare i record di un raggruppamento.
Es.: per selezionare un conteggio degli enti per tipo escludendo i tipi per i quali è presente un solo record, utilizzare il parametro HAVING:
SELECT E§TRAG, Count(*) FROM BRENTI0F
GROUP BY E§TRAG
HAVING count(*)>1
Operatore WHERE
L'operatore WHERE consente di filtrare i record selezionati (SELECT), inseriti (INSERT), aggiornati (UPDATE) ed eliminati (DELETE) in base alle condizioni specificate dopo di esso.Le condizioni di selezione sono delle espressioni booleane.
Nel caso le condizioni riguardino campi di tipo stringa, è importante ricordare che i valori sono _i_case sensitive._n_
Per ovviare a questo problema fare riferimento alle funzioni descritte nel paragrafo relativo alle _i_Operazioni sulle stringhe._n_
Sintassi:
SELECT * FROM nometabella1 WHERE nomecolonna1='Valore1' AND nomecolonna2='Valore2'
Es.:
SELECT * FROM BRENTI0F WHERE E§TRAG = 'COL'
Gli operatori matematici disponibili sono i seguenti:
- =: uguale;
- <: minore;
- >: maggiore;
- <>: diverso (maggiore o minore);
- <=: minore o uguale;
- >=: maggiore o uguale.
È possibile utilizzare più criteri assieme attraverso gli operatori logici:
- AND: le due condizioni implicate devono essere entrambe vere perché la riga venga considerata;
- OR: almeno una delle due condizioni deve essere vera perché la riga venga considerata;
- NOT: restituisce la riga solo se la condizione implicata non è vera;
Operatore LIKE
Sintassi:
SELECT campi
FROM nomefile
WHERE campo LIKE ricerca
Es.:
SELECT *
FROM BRENTI0F
WHERE E§RAGS LIKE '%ANNA%' ;
L'operatore LIKE utilizza due tipi di caratteri jolly per verificare le uguaglianze parziali. I due caratteri sono il simbolo percento '%' e l'underscore '_'. Il primo carattere jolly sostituisce un insieme di caratteri, il secondo si limita a sostituirne uno solo .
- inizia per a --> CAMPO LIKE 'A%'
- finisce per a --> CAMPO LIKE '%A'
- contiene a --> CAMPO LIKE '%A%'
SELECT RAGSOC
FROM CLIENTI
WHERE RAGSOC LIKE 'COOPERATIVA%'
Estrae tutti i clienti con Ragione Sociale che inizia con COOPERATIVA
SELECT RAGSOC
FROM CLIENTI
WHERE RAGSOC LIKE 'P_PPO'
Estrae tutti i clienti con Ragione Sociale PIPPO,POPPO,PAPPO ecc.
SELECT RAGSOC
FROM CLIENTI
WHERE STRIP(RAGSOC, TRAILING) LIKE '%SPA'
_h_Utilizzando l'operatore LIKE, l'SQL considera i campi per l'intera loro lunghezza (se voglio tutte le SPA mie clienti devo togliere con la funzione STRIP() i blank finali).
L'operatore = , al contrario, non considera i blank finali._n_
Definendo come escape il carattere punto esclamativo posso effettuare una ricerca che seleziona tutti i clienti con il carattere Underscore nella Ragione Sociale. Es:
SELECT *
FROM BRENTI0F
WHERE E§RAGS LIKE '%!_%' Escape '!'
Operatore BETWEEN
Per specificare un range di valori si puo' ricorrere all'operatore BETWEEN. Es.:
SELECT RAGSOC
FROM CLIENTI
WHERE FATTU2001 BETWEEN 1000000 AND 5000000
Per selezionare tutti i clienti con il fatturato tra 1.000.000 e 5.000.000
Operatore IN / NOT IN
Il predicato SQL IN puo' essere usato per indicare una lista di valori consentiti in una condizione oppure per sfruttare delle subquery SQL:
SELECT *
FROM Clienti
WHERE Pagam IN ('100', '101', '300', '301')
oppure
SELECT *
FROM Clienti
WHERE Pagam IN (Select cod from Pagamenti where tipo='RB')
Per estrarre solo i clienti con alcuni codici pagamento o con un pagamento di tipo Ricevuta Bancaria.
Operatore EXISTS / NOT EXISTS
EXISTS usa una subquery come condizione: la condizione è Vera se la subquery ritorna almeno una riga, ed è Falsa se la subquery non ritorna nessuna riga.
Sintassi:
SELECT columns
FROM tables
WHERE EXISTS ( subquery )
Nell'esempio seguente, per ogni dipendente presente nella tabella Employees vengono individuati nella tabella Orders tutti gli ordini che contengono "Washington" nel campo ShippingRegion.
SELECT * FROM Orders WHERE ShipRegion = 'WA'
AND EXISTS (SELECT EmployeeID FROM Employees AS Emp WHERE Emp.EmployeeID = Orders.EmployeeID)
L'operatore EXISTS può essere utilizzato anche in un'istruzione di UPDATE, DELETE o INSERT.
Instruzione INSERT
L'istruzione INSERT permette di inserire dei record in un file:Sintassi:
INSERT INTO File (NomeCampo1, NomeCampo2, NomeCampo3) VALUES ('Valore1', 'Valore1', 'Valore3')
È anche possibile inserire dei record in un file selezionandoli da un altro:
Sintassi:
INSERT INTO LibreriaDestinazione/FileDestinazione
SELECT * FROM LibreriaOrigine/FileOrigine WHERE Condizione
Istruzione UPDATE
Per aggiornare i record di un file:Sintassi:
UPDATE NomeFile SET NomeCampo1=ValoreCampo1, NomeCampo2=ValoreCampo2 (WHERE Condizione)
Esempio di aggiornamento di una tabella con un campo preso da un'altra tabella
Sintassi:
UPDATE LIB1/FILE1 A
SET A.CAMPO1=(SELECT CAMPO1 FROM LIB1/FILE2
WHERE CAMPO2=A.CAMPO2 AND CAMPO3=A.CAMPO3 AND CAMPO4=A.CAMPO4)
Istruzione DELETE
L'operatore DELETE consente di cancellare fisicamente i record di un file:Sintassi:
DELETE FROM NomeFile (WHERE Condizione)
Gestione file multimembro
Se si vuole usare un file multimembro nell'SQL prendendo in considerazione un particolare membro, è necessario seguire la seguente procedura:- fare una prima istruzione SQL che crea un ALIAS del membro:
CREATE ALIAS nomealias FOR nomefile (nomemembro)
- eseguire tutte le operazioni SQL che si vogliono fare sul membro usando come nome del file l'alias
- eseguire come ultima operazione la cancellazione dell'alias:
DROP ALIAS nomealias
Quest'ultima operazione è importante in quanto l'alias è di fatto un file.
Esportazione dei risultati di una query in un file
CPYF tramite sql: fare F13 dalla linea comandi SQL --> opzione 1 (Change session attributes), alla voce "SELECT output" mettere 3 (=File) invece che 1 (=Display), dare invio e scrivere il file e la libreria di destinazione, nonchè l'opzione di copia. A questo punto, facendo una select su un file, tutti i record selezionati verranno scritti sul file selezionato nell'F13 e non esplosi a video.ATTENZIONE: DOPO L'OPERAZIONE BISOGNA RICORDARSI DI RIPRISTINARE L'F13 CON "SELECT output" A 1
Creazione di viste logiche
Con SQL è anche possibile creare delle viste logiche (LF) su un File Fisico (PF):
CREATE INDEX liblogico/filelogico
ON libfisico/filefisico (chiave1, chiave2, ecc..)
Operazioni sulle stringhe
Funzione SUBSTR
Per estrapolare delle sottostringhe:
SELECT SUBSTR(RAGSOC, 1, 25)
FROM CLIENTI
Per leggere solo i primi 25 caratteri della Ragione Sociale
Update di un campo con la sottostringa di un'altro campo:
update file set a=substr(b, x, y)
dove x sta per la pos.iniziale e y il n° di caratteri da prendere
Modificare una sottostringa di un campo
Se volessimo modificare una sottostringa di un campo, non potremmo usare un update set substr(...), ma una sintassi di questo tipo:
update FILE set CAMPO='xxxxx' concat substr(CAMPO, 6) where substr(CAMPO, 1, 5)= 'yyyyy'
Funzione CONCAT
Per concatenare 2 campi stringa bisogna ricorrere al CONCAT:
SELECT COUNT(DISTINCT(CONCAT(Cdnaz,Cdpag))) FROM Clienti
equivalente a
SELECT COUNT(DISTINCT Cdnaz CONCAT Cdpag) FROM Clienti
Se avessimo un campo numerico potremmo usare DIGITS(campo) all'interno del CONCAT.
Update di un campo concatenando due campi
update file set a=b concat c
Trasformazione MAIUSCOLE/minuscole
Per effettuare la traformazione dei valori di un campo in caratteri solo maiuscoli, si utilizza la funzione UPPER() oppure UCASE().Per effettuare la traformazione in caratteri solo minuscoli, utilizzare LOWER() o LCASE().
Es.:
SELECT * FROM BRENTI0F
WHERE lower(E§RAGS) LIKE 'a%'
ORDER BY E§RAGS
Esegue la selezione di tutti gli enti la cui ragione sociale cominci per 'a', indipendentemente se maiuscola o minuscola. Si noti che la funzione lower() agisce solo sulla condizione, non modifica la visualizzazione dei valori dei campi selezionati. Si evidenza anche che, qualora la condizione fosse stata LIKE 'A%', non sarebbe stato restituito alcun risultato, in quanto la condizione della where è case sensitive.
Rimozione degli spazi (TRIM / LTRIM / RTRIM)
La funzione TRIM() rimuove gli eventuali spazi (blank) iniziali e finali di una stringa.La funzione LTRIM() rimuove invece i soli spazi iniziali, mentre RTRIM() i soli spazi finali.
Campi stringa contenenti un valore con l'apice
Può creare qualche problema la selezione di campi con il valore contenente il carattere apice, ad esempio, se sulla nostra tabella clienti dovessimo selezionare quelli con Cognome D'Amato:
SELECT * FROM CLIENTI
WHERE COGNOME = 'DAMATO'
Per evitare che l'apostrofo interno al valore venga rilevato dal database come la chiusura della stringa, è necessario utilizzare 2 apici.
Operazioni sui numerici
Conversione di numeri in stringhe_n_
Per confrontare variabili alfanumeriche e numeriche ci sono diverse modalità:
alfa = char(numerica)
alfa = DIGITS(numerica)
Arrotondamenti con SQL_n_
La funzione TRUNC(nomecampo, n ) o TRUNCATE(nomecampo, n ) arrotonda sempre per difetto, mentre la funzione ROUND(nomecampo, n ) arrotonda con la regola dello 0,5 (al giusto).
SELECT TRUNCATE(873.726, 2),
TRUNCATE(873.726, 1),
TRUNCATE(873.726, 0),
TRUNCATE(873.726, -1),
TRUNCATE(873.726, -2),
TRUNCATE(873.726, -3)
FROM TABLEX
Questo esempio restituisce:
0873.720 0873.700 0873.000 0870.000 0800.000 0000.000
SELECT ROUND(873.726, 2),
ROUND(873.726, 1),
ROUND(873.726, 0),
ROUND(873.726, -1),
ROUND(873.726, -2),
ROUND(873.726, -3),
ROUND(873.726, -4)
FROM TABLEX
Questo esempio restituisce:
0873.730 0873.700 0874.000 0870.000 0900.000 1000.000 0000.000
Divisione e problemi con gli Integer_n_
Se in un'istruzione SQL eseguiamo una divisione fra due numeri interi, il risultato viene presentato come intero e quindi senza virgole. Per risolvere il problema si può usare DEC() oppure:
SELECT DEC(a)/dec(b) AS C from Tabel
SELECT 1.0*A/B AS C from TABEL
Operazioni sulle date
Se ho un campo di tipo data in un file posso fare anche delle operazioni di questo tipo:
select (CURRENT DATE - Datacreaz) Giorni, CURRENT DATE , Datacreaz from Miofile
In questo caso, però, il risultato del campo Giorni è nel formato YYYYMMDD, quindi un risultato 210 significa 2 mesi e 10 giorni .... un po' scomodo.
Un metodo migliore per calcolare il numero di giorni è il seguente:
SELECT (days(CURRENT DATE) - days(Datacreaz)) Giorni, CURRENT DATE , Datacreaz FROM Miofile
Estrarre il numero della settimana con SQL
select week(date('31.12.2002')) from file --> 53
select week_iso(date('31.12.2002')) from file --> 01
Funzione RRN()
E' possibile anche ottenere il numero relativo di record con un'istruzione SQL:
SELECT RRN(nomefile)
FROM nomefile
WHERE campo = 'valore'
Supponiamo di avere un file di movimenti contabili e di voler rigenerare il campo numero movimento seguendo una nuova numerazione: prendendo il file movimenti ACG MOAZ200F e il campo NUMOV, vogliamo fare in modo che tutti i movimenti presenti nel file vengano rinumerati dal numero 1.000.000 in avanti:
UPDATE moaz200f SET numov=1000000+RRN(moaz200f)
Campi condizionati: CASE, WHEN, ELSE, END
Supponiamo di voler estrarre da un file di righe ordini cliente con la data ancora nel formato AAMMGG, la stessa data nel formato AAAAMMGG:Nome del file OCRIG00F
Campi: NRRER=Numero ordine , DTCCR=Data consegna AAMMGG
SELECT NRRER, CASE WHEN DTCCR=0 THEN 0
WHEN SUBSTR(DIGITS(DTCCR), 1, 2) = '00' THEN 20000000+DTCCR
ELSE 19000000+DTCCR
END
AS DATADAOTTO
FROM OCRIG00F
In questo caso viene considerata anche la possibilità che la data sia zero.
ORDINAMENTO PER DUE CAMPI ALTERNATI
Es.: Ordino in modo alternativo per R§DTCR, se maggiore 20070101 o data inserimento
se la R§DTCR è <=20070101
SELECT r§tdoc, r§ndoc ,
case when R§dtcr>20070101 then r§DTCR else R§DTin
end as data3 FROM v5rdoc0f ORDER BY DATA3
File di sistema
SELECT * FROM SYSCOLUMNS = da le definizione di tutti i campi di tutti i file del sistemaSELECT * FROM SYSTABLES = da le definizione di tutte le tabelle di sistema
Utilizzo di un cursore per la lettura di dati in SQLRPGLE
Il recupero dei dati tramite SQL in SQLRPGLE avviene attraverso l'utilizzo di un cursore.Le operazioni necessarie per la lettura di record con un cursore sono le seguenti:
- DECLARE: dichiarazione di un cursore
- PREPARE: preparazione di una istruzione SQL eseguibile a partire da una variabile stringa
- OPEN: apertura del cursore
- FETCH: spostamento tra i record risultanti
- CLOSE: chiusura del cursore
Le istruzioni SQL embedded in un membro di tipo SQLRPGLE sono comprese tra un'istruzione di apertura C/EXEC SQL e una di chiusura C/END-EXEC e sono caratterizzate da un tipo riga C+.
C/EXEC SQL
C+ ...
C/END-EXEC
N.B.: Le istruzioni SQL non possono andare oltre la posizione 80 nel codice del programma.
All'interno delle istruzioni SQL embedded è possibile fare riferimento a variabili host definite in RPGLE. Nell'esempio sotto riportato, nell'istruzione SQL si fa riferimento alla variabile RPG SelectStm, facendo precedere il nome della variabile da ':'. E' importante ricordare che non è possibile utilizzare nei nomi delle variabili host caratteri speciali (come £), in quanto viene generato un errore del precompilatore SQL. Inoltre, nomi di variabili che iniziano con SQ , SQL e DNS sono da considerarsi riservati all'uso del DBMS.
D SelectStm S 200 INZ
L(PUN)
-
C EVAL SelectStm='SELECT A§ARTI FROM BRARTI0F'
C+ PREPARE S1 from :SelectStm
C/END-EXEC
Si distinguono due tipi di cursore:
- SERIAL CURSOR (supporta soltanto lo spostamento in avanti di un record alla volta);
- SCROLLABLE CURSOR (consente lo spostamento avanti e indietro all'interno dei record risultanti dall'apertura del cursore).
Serial cursor
Questo tipo di cursore supporta soltanto lo spostamento in avanti di un record alla volta. Declare
Il cursore è definito come:
C/EXEC SQL
C+ DECLARE C1 cursor for S1
C/END-EXEC
Dove C1 è il nome del cursore e S1 è l'istruzione SQL resa eseguibile tramite l'istruzione PREPARE.
Prepare
Prepara un'istruzione SQL eseguibile a partire da una variabile stringa:
C/EXEC SQL
C+ PREPARE S1 from :SelectStm
C/END-EXEC
Dove S1 è l'istruzione SQL resa eseguibile e SelectStm è la variabile host stringa che contiene l'istruzione SELECT SQL da eseguire.
Open
C/Exec SQL
C+ OPEN C1
C/End-Exec
Dove C1 è il nome del cursore da aprire.
Quando il cursore viene aperto, è posizionato prima della prima riga nella tabella dei risultati.
Fetch
Questo tipo di cursore supporta soltanto lo spostamento in avanti di un record alla volta, tramite l'istruzione FETCH.Una volta raggiunta la fine dei dati (SQLCOD=100) è necessario chiudere e riaprire il cursore per accedere nuovamente ai dati.
C/Exec SQL
C+ FETCH C1
C+ INTO :HostVariable
C/End-Exec
Se sono specificate variabili host (tramite un elenco di singole variabili separate da virgola oppure tramite una DS) con la clausola INTO, SQL esegue lo spostamento dei valori della riga corrente nelle variabili host del programma.
In RPG, un array è una DS a ricorrenze multiple (OCCURS). Un array può essere referenziato in una istruzione FETCH soltanto quando si esegue la fetch multipla (di più righe), o in un'istruzione INSERT quando si esegue una insert a blocchi.
Close
C/EXEC SQL
C+ CLOSE C1
C/END-EXEC
Dove C1 è il nome del cursore da chiudere.
Scrollable cursor
Questo tipo di cursore consente lo spostamento avanti e indietro all'interno dei record risultanti dall'apertura del cursore. Declare
Il cursore è definito con l'utilizzo della parola chiave SCROLL:
C/EXEC SQL
C+ DECLARE C1 SCROLL cursor for S1
C/END-EXEC
Dove C1 è il nome del cursore e S1 è l'istruzione SQL resa eseguibile tramite l'istruzione PREPARE.
Prepare
Prepara un'istruzione SQL eseguibile a partire da una variabile stringa:
C/EXEC SQL
C+ PREPARE S1 from :SelectStm
C/END-EXEC
Dove S1 è l'istruzione SQL resa eseguibile e SelectStm è la variabile host stringa che contiene l'istruzione SELECT SQL da eseguire.
Open
C/Exec SQL
C+ OPEN C1
C/End-Exec
Dove C1 è il nome del cursore da aprire.
Quando il cursore viene aperto, è posizionato prima della prima riga nella tabella dei risultati.
Fetch
Questo tipo di cursore consente lo spostamento avanti e indietro all'interno dei record risultanti dall'apertura del cursore in base all'opzione specificata per l'istruzione FETCH.Una volta raggiunta la fine o l'inizio dei dati (SQLCOD=100)* non è necessario chiudere e riaprire il cursore per accedere nuovamente ai dati.
Se sono specificate variabili host (tramite un elenco di singole variabili separate da virgola oppure tramite una DS) con la clausola INTO, SQL esegue lo spostamento dei valori della riga corrente nelle variabili host del programma.
In RPG, un array è una DS a ricorrenze multiple (OCCURS). Un array può essere referenziato in una istruzione FETCH soltanto quando si esegue la fetch multipla (di più righe) o in un'istruzione INSERT quando si esegue una insert a blocchi.
* NOTA: SQLCOD, SQLERM e SQLSTATE sono variabili RPG dichiarate automaticamente dal compilatore e accessibili nelle specifiche RPG.
Es.:
C IF SQLCOD=100
C LEAVE
C ENDIF
Opzioni per l'istruzione Fetch
- NEXT: Posiziona il cursore sulla riga successiva (è l'opzione predefinita se nessuna opzione è specificata)
C/Exec SQL
C+ FETCH NEXT
C+ FROM C1
C+ INTO :HostVariable
C/End-Exec
- PRIOR: Posiziona il cursore sulla riga precedente
C/Exec SQL
C+ FETCH PRIOR
C+ FROM C1
C+ INTO :HostVariable
C/End-Exec
- FIRST: Posiziona il cursore sulla prima riga
C/Exec SQL
C+ FETCH FIRST
C+ FROM C1
C+ INTO :HostVariable
C/End-Exec
- LAST: Posiziona il cursore sull'ultima riga
C/Exec SQL
C+ FETCH LAST
C+ FROM C1
C+ INTO :HostVariable
C/End-Exec
- BEFORE: Posiziona il cursore prima della prima riga
C/Exec SQL
C+ FETCH BEFORE
C+ FROM C1
C/End-Exec
N.B.: Non è possibile specificare variabili host con la clausola INTO per l'opzione BEFORE.
- AFTER: Posiziona il cursore dopo l'ultima riga
C/Exec SQL
C+ FETCH AFTER
C+ FROM C1
C/End-Exec
N.B.: Non è possibile specificare variabili host con la clausola INTO per l'opzione AFTER.
- CURRENT: Esegue la rilettura della riga corrente
C/Exec SQL
C+ FETCH CURRENT
C+ FROM C1
C+ INTO :HostVariable
C/End-Exec
- RELATIVE: Esegue il posizionamento (in base al numero specificato in una variabile host di tipo integer) in relazione al record corrente del cursore.
Specificare RecNum uguale a 0 è equivalente all'utilizzo dell'opzione CURRENT.
C/Exec SQL
C+ FETCH RELATIVE :RecNum
C+ FROM C1
C+ INTO :HostVariable
C/End-Exec
Close
C/EXEC SQL
C+ CLOSE C1
C/END-EXEC
Dove C1 è il nome del cursore da chiudere.
Accorgimenti relativi alle performance
File fisici e logici
E' preferibile utilizzare nelle istruzioni SQL riferimenti ai file fisici, piuttosto che ai file logici.Infatti, con i file fisici l'ottimizzazione delle query viene affidata a partire dalla V5R2 al SQE (SQL Query Engine), che è più performante e che farà automaticamente uso dell'indice e (quindi del logico) più adatto.
In caso contrario verrà invece utilizzato il vecchio CQE (Classic Query Engine), le cui prestazioni sono nettamente inferiori.
Add new attachment
Only authorized users are allowed to upload new attachments.
G’day (anonymous guest)
My Prefs
JSPWiki v2.8.0