Sintassi SQL accettata da eXtraWay in materia di SELECT

Introduzione

Il server eXtraWay non è un DataBase Relazionale e quindi non prevede di implementare pienamente la sintassi SQL bensì limitarsi allo sviluppo delle funzionalità più probabilmente utili a sviluppatori e fruitori di Db XML.

Nella fattispecie, quindi, il server accetta condizioni di Join di varia natura (espresse nella clausola from o nella clausola where) purché la condizione espressa sia di uguaglianza. Non sono accettate altre forme di Join (disuguaglianze o altre condizioni di selezione).

Fatta salva questa principale condizione l'attuale implementazione dell'interprete SQL entro il server eXtraWay accetta tutti gli operatori più direttamente riconducibili a quelli leciti nel linguaggio di ricerca nativo eXtraWay. Vediamo, caso per caso, di cosa stiamo parlando.

La Clausola SELECT

La clausola SELECT prevede l'elencazione delle colonne (separate da virgole) che si intendono selezionare. Esse possono essere rappresentate da:

E' consentito l'uso della forma 'name as shotname' per successive semplificazioni nel resto dello statement SQL.
Parimenti, l'uso dei nomi di colonna può corrispondere, di fatto, ad altri 'shortnames' dichiarati, ad esempio, nella clausola FROM.

Nella clausola SELECT non sono accettate, nell'attuale implementazione, le forme:

Alcune di queste funzionalità, per contro, sono ammesse in fase di Update delle tabelle.

La Clausola FROM

La clausola FROM prevede l'elencazione delle tabelle (separate da virgole) sulle quali si estende la selezione e sulle quali vengono svolti i Join. La clausola può inoltre comprendere condizioni di Join a patto che comportino uguaglianza tra valori di colonne. Sono quindi consentite le forme:

Nota:
Quando una tabella, corrispondente ad una unità informativa di un archivio eXtraWay, è identificabile tramite il nome dell'elemento che qualifica la suddetta unità ed esso presenta caratteri non ammessi dalla sinassi SQL (quindi presenta caratteri che non siano ne lettere ne cifre e che non siano l'underscore '_'), la forma che prevede l'uso dell'operatore AS seguito da una shorthand per il nome tabella diviene obbligatoria.

Viste e Table Expression nella clausola FROM

La sintassi SQL prevede, inoltre, che si possano sfruttare in uno statement SELECT anche forme composite quali la configurazione di viste, di table expressions e di common table expressions. Il presente documento non intende entrare nel dettaglio di queste specifiche, ci sarà sufficiente darne una rapida panoramica e descrivere come sia stata applicata ad eXtraWay una di queste forme.
Le view è il risultato di una query che viene valutata dinamicamente ogni volta che ad essa si fa riferimento. La query viene stabilita una tantum ed utilizzata per definire la view. Una volta definita la view essa può essere referenziata un numero indefinito di volte negli statement SELECT. La sintassi prevista per definire ed utilizzare le view è la seguente...

create view view_name(col1_name, col2_name, ...)
as select ...
   from ...
   where ...

...per poi farne uso ad esempio come...

select tabella.colonna, view_name.col1_name
from tabella, view_name
where ... 

La table expression è rappresentata da una sub query che definisce dinamicamente, ed in modo del tutto volatile, una sorta di tabella derivata che può essere utilizzata nello statemente SELECT (entro la clausola FROM) al pari di una view. Mentre la view, una volta definita, può essere utilizzata indefinitamente, una table expression è una semplice ricerca che ha valenza solo ed esclusivamente nell'ambito dello statement SELECT in corso di elaborazione. La sintassi prevista per la dichiarazione e l'utilizzo di una table expression in ricerca è la seguente...

select tabella.colonna, t_exp.col1
from tabella, (select ...
               from ...
               where...) as t_exp(col1, ...)
where ...

Come estensione della table expression, la common table expression prevede la definizione di una sorta di view temporanea che precede la dichiarazione dello statement SELECT che può poi far uso di tale view. La sintassi per la dichiarazione e l'utilizzo di una common table expression in ricerca è la seguene...

whit c_t_exp(col1, col2, ...)
as (select ...
    from ...
    where...)
select tabella.col, c_t_exp.col2
from tabella, c_t_exp
where ...

Nell'implementazione dell'interprete SQL per eXtraWay nessuna delle 3 forme precedentemente descritte è stata effettivamente implementata. La prima prevede la definizione di una sorta di ricerca frequente, funzionalità pienamente supportata da eXtraWay ma che non si è ritenuto di dover ancora implementare. Per quanto concerne il secondo ed il terzo caso essi si avvicinano maggiormente al concetto di raffinamento esistente per il motore eXtraWay quindi s'è deciso di implementare una variante delle sintassi indicate per perseguire esattamente quest'obiettivo.

Compiere quanto detto consiste nell'implementare una via di mezzo tra una table expression ed una common table expression. Compiere un raffinamento, infatti, consiste nel compiere una ricerca e, conseguentemente, effettuare una restrizione della ricerca compiendo sul subset da essa identificato un ulteriore ricerca. La formula somiglia quanto più alla common table expression ma per motivi tecnici essa è stata realizzata seguendo ed adeguando alle esigenze eXtraWay la sintassi della table expression.
Com'è stato evidenziato precedentemente, la definzione della table expression prevede che essa venga identificata da uno statement SELECT direttamente entro la clausola FROM dello statement SELECT che potremmo definire il più esterno. Avendo scelto di non consentire direttamente la nidificazione delle SELECT (operazione per altro realizzabile in futuro senza particolari impatti) la soluzione più naturale è stata quella di sostituire la SELECT più interna con l'identificativo della selezione che da essa deriva. Tale identificativo è rappresentato da una sequenza di caratteri che inizia, per definizione, col carattere 3. Questa caratteristica fa si che il nome di tale identificativo non risulti un nome di tabella valido. Esso va quindi racchiuso tra doppi apici per essere sintatticamente accettabile. Per semplificare l'utilizzo di questo identificativo, ad esso può essere affinacato uno 'shortname' per messo dell'operatore AS.
Il seguente esempio chiarirà l'uso che si è previsto di fare di questa forma di raffinamento. Come detto si deve prima compiere una selezione. Essa può essere effettuata sia nel linguaggio nativo eXtraWay che con uno statement SQL. In questo secondo caso il comando inviato al server deve specificare che si richiede un elenco di unità informative, compatibile con il formato di eXtraWay, e non la produzione della tabella temporanea altrimenti calcolata. La nostra ricerca, quindi, da luogo all'identificativo. Diciamo ad esempio che la ricerca sia...

select * from comuni where comuni.provincia='Bologna'

Come detto più volte, il risultato che possiamo gestire è un identificativo di selezione e non una tabella temporanea. Ne consegue che quello che si deve ottenere risulterà di fatto indipendente da quali colonne vengono selezionate.

Nota:
Condizione necessaria e sufficiente perché la selezione sulla quale si procederà in raffinamento sia considerata valida è che essa comprenda unità informative appartenenti ad un solo tipo, quindi riconducibili a colonne appartenenti ad una sola tabella.

L'operazione precedentemente descritta ci da un file di selezione eXtraWay identificato, ad esempio, come 3sefe096013a02.
un possibile uso di questo identificatore di selezione, sotto forma di table expression in uno statement SELECT potrebbe quindi essere il seguente...

select rubrica.nome, view.regione
from rubrica, "3sefe096013a02" as view
where rubrica.cap=view.cap and view.cap>40120

La Clausola WHERE

La clausola WHERE esprime la condizione secondo la quale vengono selezionati i record. Le condizioni riguardano i valori assunti dalle colonne o espressioni booleane tra colonne. In particolare sono accettati:

Nota:
Il trattamento delle ricerce per uguaglianza e somiglianza (predicato 'like') opera diversamente a seconda del canale eXtraWay chiamato in causa. Questo perché ci sembra lecito supporre che l'operatore che compie selezioni su un IR-XmlDBMS sappia che esso si comporta naturalmente da Information Retrieval e non come un RDBMS. Ne consegue che si può sottolineare che:
  • Il predicato 'like' si applica sempre e comunque nel momento in cui si intende far uso di Wild Cards ma consente la ricerca di singoli termini su canali a doppia indicizzazione sui quali l'operatore '=' viene interpretato in qualità di as is richiedendo quindi che quanto espresso tra apici sia corrispondente all'intero contenuto del canale richiesto.
  • L'operatore '=' si applica quindi per le riceche esatte, inerenti l'intero contenuto del canale in oggetto ed ha un comportamento ben chiaro e delineato per i canali a singola indicizzazione ("one") e per quelli a doppia indicizzazione ("double") ove viene ricercato l'intero contenuto del cnaale. Per i canali ad indicizzazione multi valore ("multi") la ricerca di un match perfetto e completo non è percorribile quindi l'operatore '=' si assume applicarsi all'uguaglianza di singoli termini presenti nel canale. Questa rappresenta la sola sostanziale differenza tra il comportamento del server eXtraWay e quello di un RDMBS.

Nella clausola WHERE non sono accettate, nell'attuale implementazione, le forme:

La Clausola ORDER BY

La clausola ORDER BY esprime la condizione secondo la quale vengono ordinati i record selezionati. Le condizioni riguardano colonne delle tabelle selezionate e consentono ordinamenti ascendenti e discendenti. Viene quindi accettata una o più forme "'nome colonna' [asc|desc]" separate tra loro da una virgola.

Modalità di richiesta ed OutPut

Per venire incontro a diverse tipologie di esigenze esistono due diversi stili di input della richiesta di selezione e, conseguentemente, due diversi stili di output.

Di fatto due sono le possibili esigenze:

Corrispondentemente ci sono due tipi di possibili richieste:

Simulazione di una ricerca eXtraWay

Questo tipo d'operazione è certamente la più semplice ma, al contempo, quella che offre meno possibilità. Sarà sufficiente esprimere nella frase di ricerca eXtraWay di una comune operazione di ricerca uno statement SQL completo di ogni sua parte e che figuri - in testa, in coda o in qualsiasi altra posizione - il modificatore "[?SQL]".

Il server provvederà a rimuovere tale modificatore ed eseguire lo statement espresso producendo un file di selezione in tutto e per tutto equivalente a quelli ottenibili con le comuni ricerche in linguaggio nativo eXtraWay. Ovviamente, non potendo rappresentare in questo modo dati composti provenienti da tabelle diverse, questa modalità ha delle restrizioni.

La sola vera restrizione si ha per il fatto che le colonne selezionate DEVONO appartenere tutte alla stessa tabella. Se così non fosse, la richiesta produrrebbe un errore sintattico.

Lo statement può quindi coinvolgere colonne di tabelle differenti e può compiere join ed ordinamenti facendo uso di tali colonne a patto che selezioni colonne di una sola tabella.

Nota:
La scelta delle colonne selezionate, in questo frangente, è assolutamente ininfluente in quanto vengono selezionate intere Unità Informative e non delle singole righe estratte da esse. A tal fine si suggerisce di selezionare una colonna sola per ridurre il carico di lavoro del server che, vista la tipologia dell'esito della selezione, sarebbe in grossa parte inutile qualora si selezionino numerose colonne. In presenza di più tabelle coinvolte la richiesta di colonne selezionate non deve essere effettuata su '*' ne su colonne appartenenti a diverse tabelle.

Espressione diretta di uno statement SQL

Questo tipo di operazione è la più completa e versatile. Consente di ottenere risultati in tutto e per tutto equivalenti a quelli ottenibili con la Simulazione di una ricerca eXtraWay, seguendo le stesse identiche restrizioni, ma consente anche di rappresentare la tabella temporanea esito della Select in forma XML. In essa saranno riconoscibili le righe e le colonne selezionate e se ne potrà dare una corretta rappresentazione esteriore.

Il comando va inviato al server per mezzo di uno dei comandi XML resi disponibili. In particolare il comando in esame è il comando '0x0d'. La possibilità di ottenere un file di selezione standard anche in questo caso si ottiene esplicitando il bit '1'.

La forma del comando è:

<?xml version="1.0" encoding="windows1252"?>
<cmd c="xd" bits="0">
<bst>
   ...Statement SQL...
</bst>
</cmd>

La forma della risposta sarà:

<?xml version="1.0" encoding="utf-8" ?> 
<rsp ack="1" e="0">
   <sqltab name="tabella">
      <!-- 
       SQL Statement: ...
      --> 
      <sqlcolumns cols="4" rows="299">
         <sqlcomumn name="colonna_1" /> 
         <sqlcomumn name="colonna_2" /> 
         <sqlcomumn name="colonna_3" /> 
         <sqlcomumn name="colonna_4" /> 
      </sqlcolumns>
      <sqlrow>
         <cell>Valore riga 1 colonna 1</cell> 
         <cell>Valore riga 1 colonna 2</cell> 
         <cell>Valore riga 1 colonna 3</cell> 
         <cell>Valore riga 1 colonna 4</cell> 
      </sqlrow>
      <sqlrow>
         <cell>Valore riga 2 colonna 1</cell> 
         <cell>Valore riga 2 colonna 2</cell> 
         <cell>Valore riga 2 colonna 3</cell> 
         <cell>Valore riga 2 colonna 4</cell> 
      </sqlrow>
      ...
      <sqlrow>
         <cell>Valore riga n colonna 1</cell> 
         <cell>Valore riga n colonna 2</cell> 
         <cell>Valore riga n colonna 3</cell> 
         <cell>Valore riga n colonna 4</cell> 
      </sqlrow>
   </sqltab>
</rsp>
Osservazioni:
L'attributo name dell'elemento sqltab viene valorizzato se e solo se il risultato esprime colonne di una tabella ed una soltanto. In ogni altro caso ove il join eseguito comporti la selezione di colonne appartenenti a più tabelle, l'attributo viene omesso.

Esempi di Select accettate

Ecco di seguito alcuni esempi si statement SQL di ricerca accettate dal server.

Esempio 1

select xcrwl_Document.titolo,
       xcrwl_Target.t_nome_target,
       xcrwl_Target.percorso_http,
       xcrwl_Target.percorso
from xcrwl_Target,
     xcrwl_Document
where xcrwl_Target.timeout between 100 and 200 and
      xcrwl_Target.t_nome_target=xcrwl_Document.d_nome_target

La Select non può dar luogo ad un file di selezione in quanto seleziona colonne da tabelle diverse.

Esempio 2

select struttura_esterna.struest_nome,
       persona_esterna.persest_cognome,
       persona_esterna.persest_nome,
       persona_esterna.persest_matricola
from persona_esterna,
     struttura_esterna,
     comune
where struttura_esterna.struest_coduff = persona_esterna.persest_appartenenzacoduff and
      struttura_esterna.struest_indirizzocomune = comune.comuni_nome and
      comune.comuni_regione = 'lazio'

Anche quest'espressione non può dar luogo ad un file di selezione in quanto seleziona colonne di tabelle diverse. Si compiono Join tra 3 tabelle differenti selezionando in fine colonne solo da 2 di esse. Tutta la condizione di Join è espressa nella clausola WHERE.

Esempio 3

select struttura_esterna.struest_nome,
       persona_esterna.persest_cognome,
       persona_esterna.persest_nome,
       persona_esterna.persest_matricola
from persona_esterna join struttura_esterna join comune
     on struttura_esterna.struest_coduff = persona_esterna.persest_appartenenzacoduff
     on struttura_esterna.struest_indirizzocomune = comune.comuni_nome
where comune.comuni_regione = 'lazio'

Fondamentalmente identico all'esempio precedente ma con l'espressione delle clausole di join espresse sotto forma di uguaglianza dei valori di colonne di tabelle diverse direttamente nella clausola FROM. Nella clausola WHERE viene espressa l'unica condizione non altresì esprimibile.

Esempio 4

select struttura_esterna.struest_nome,
       persona_esterna.persest_cognome,
       persona_esterna.persest_nome,
       persona_esterna.persest_matricola
from comune, persona_esterna join struttura_esterna
     on struttura_esterna.struest_coduff = persona_esterna.persest_appartenenzacoduff
where struttura_esterna.struest_indirizzocomune = comune.comuni_nome and
      comune.comuni_regione = 'lazio'

Rifacendoci ancora una volta agli esempi precedenti abbiamo la stessa identica ricerca nella quale viene espresso uno dei due Join tra colonne nella clausola FROM e l'altro nella clausola WHERE unitamente alla condizione su un particolare valore della colonna comuni_regione.

Esempio 5

select struttura_esterna.struest_nome,
       persona_esterna.persest_cognome,
       persona_esterna.persest_nome,
       persona_esterna.persest_matricola
from comune, struttura_esterna left join persona_esterna
     on struttura_esterna.struest_coduff = persona_esterna.persest_appartenenzacoduff
where struttura_esterna.struest_indirizzocomune = comune.comuni_nome and
      comune.comuni_regione = 'lazio'
order by struttura_esterna.struest_nome,
         persona_esterna.persest_cognome

Condizione di ricerca derivata dalle precedenti ma composta con un Left Join. L'esito della selezione viene poi ordinato in base alle colonne espresse.

Esempio 6

select se.struest_nome,
       pe.persest_cognome,
       pe.persest_nome,
       pe.persest_matricola
from comune, persona_esterna as pe right join struttura_esterna as se
     on pe.persest_appartenenzacoduff = se.struest_coduff
where se.struest_indirizzocomune = comune.comuni_nome and
      comune.comuni_regione = 'lazio'

Condizione di ricerca derivata dalle precedenti ma composta con un Right Join. Alla ricerca viene applicata la clausola AS per semplificarne la sintassi

Esempio 7

Tutti gli esempi, da 2 a 6, possono condurre alla produzione di un semplice file di selezione - che quindi fa riferimento alle Unità Informative, a patto che le colonne selezionate appartengano ad una sola tabella. Privando ognuno di quegli esempi della selezione, ad esempio, della colonna struttura_esterna.struest_nome il gioco è fatto!

Si fa notare, però, che il numero di documenti selezionati nei suddetti esempi potrebbe non corrispondere al numero delle righe selezionate nella tabella temporanea esito della select in quanto lo statement SQL può prevedere condizioni di right join o left join che conducono a selezionare, ad esempio, solo colonne di una data tabella. Se le colonne richieste, al termine della select, non appartengono a quella tabella, il numero di documenti che il server introduce nella selezione prodotta può risultare inferiore al numero di righe che si selezionerebbero richiedendo il rendering della tabella XML dei risultati.

Quanto detto vale anche in presenza di ordinamento che dovesse coinvolgere colonne di tabelle non selezionate.

A partire da:
13.0.2.*
Il trattamento delle table expression in ricerca viene introdotto dalla versione 18.0.4.*
Date
2007/03/01 09:13:17

Torna a Introduzione all'uso di SQL in eXtraWay


HighWay/eXtraWay Project - Frequently Asked Questions (Doxygen 1.6.1)