Firebird Documentation Index → Guida rapida per Firebird 2 → Operare sulle basi di dati |
In questa parte del manuale sarà spiegato:
come collegarsi ad una base di dati esistente,
come creare una nuova base di dati,
quali sono alcune informazioni fondamentali da sapere sul linguaggio SQL di Firebird.
Quando sono coinvolte connessioni remote, si userà soltanto il protocollo TCP/IP che è in assoluto quello più raccomandato.
Per connettersi ad una base di dati o crearne una, bisogna procurare, tra le altre cose, una stringa di connessione (in inglese connection string)al programma client; oppure, se si è programmatori, la stringa di connessione va consegnata alle proocedure che si stanno utilizzando. La stringa di connessione identifica univocamente il luogo in cui la base di dati risiede, sia essa nel vostro computer, nella rete locale o in internet.
Una connessione locale esplicita consiste del percorso più il nome del file esatto nel formato nativo del sistema operativo usato nella macchina server, per esempio
su un server Linux oppure altro Unix:
/opt/firebird/examples/empbuild/employee.fdb
su un server Windows:
C:\Biologia\Dati\Primati\Scimmie\popolazione.fdb
Molti programmi accettano anche percorsi relativi, ad esempio
«..\examples\empbuild\employee.fdb
»,
ma vanno usati con cautela perchè non sempre è ovvio come vengano
espansi. Ricevere un messaggio di errore è abbastanza fastidioso ma
umano, ma modificare una base di dati pensando di essere connessi ad
un'altra è diabolico.
Invece di un percorso ad un file, la connessione locale potrebbe
essere anche un semplice alias della base di dati
che è definito nel file aliases.conf
, come
spiegato precedentemente. Il
formato dell'alias dipende solo da come è scritto nel file degli
alias, non dal sistema di file del server. Alcuni esempi sono:
frankzappa
briscola.fdb
ricette_di_mamma
Se il collegamento locale non funziona, potrebbe essere perchè
il protocollo di connessione locale non funziona bene sulla vostra
macchina. Su Windows Vista, 2003 o XP con i terminal services
abilitati, questo può essere risolto mettendo il
parametro IpcName
al valore
Global\FIREBIRD
nel file di configurazione
firebird.conf
(non dimenticate di togliere il
commento al parametro e di far ripartire il server). Da Firebird
2.0.1, Global\FIREBIRD
è già il default sui
sistemi Windows con i terminal services abilitati.
Se non basta impostare IpcName
e il
protocollo locale ancora non va, si può sempre aggirare il problema
mettendo «localhost:
» prima del
percorso alla base dati o all'alias, trasformandolo così in una
stringa di connessione TCP/IP (di seguito).
Una stringa di connessione TCP/IP consiste di:
il nome di un server oppure del suo indirizzo IP
seguito dal carattere di due punti
(«:
»)
seguito o dal percorso assoluto e nome del file della base dati sul server, o da un alias definito sulla macchina server.
Esempi:
Su Linux/Unix:
pongo:/opt/firebird/examples/empbuild/employee.fdb
bongo:furia_cavallo_del_west
112.179.0.1:/var/Firebird/DBMS/farfalle.fdb
localhost:tresette.fdb
Su Windows:
decimo:C:\Biologia\DBMS\Primati\Scimmie\distribuzioni.fdb
settimo:D:\Altri\DBMS\Prove\LezioniPhp.fdb
127.0.0.1:QuiQuoQua
Notare come la stringa di connessione attraverso l'alias non da' affatto nessuna informazione sul sistema operativo del server. E infatti non dovrebbe: in tal modo si comunica ad un Firebird server Linux o ad un Firebird server Windows allo stesso modo. Specificare il percorso esplicito ad una base dati è una delle rare occasioni in cui bisogna conoscere la differenza.
Un database di esempio è nel direttorio examples/empbuild
dell'installazione di
Firebird col nome employee.fdb
. Si può usare questo
database per farci i propri esperimenti e vedere come funziona il
tutto.
Spostandolo o copiandolo altrove, assicurarsi di metterlo su un disco fisicamente collegato alla propria macchina server. Le condivisioni, i dischi mappati, o, su Unix e Linux, i sistemi di file montati sulle periferiche SMB (cioè Samba) non funzionano. La stessa regola vale per ogni database che viene creato o che si intende usare.
Per collegarsi ad una base di dati Firebird bisogna autenticarsi
con un nome utente ed una parola d'ordine validi (cioè username e
password). Per agire sugli oggetti della base di dati, cioè le tabelle,
le viste, ecc., bisogna possedere permessi espliciti su quegli oggetti,
a meno che non se ne sia proprietari (cioè creati dall'utente stesso)
oppure l'utente connesso è SYSDBA. Nel
database d'esempio employee.fdb
, sono stati dati
abbastanza permessi a PUBLIC (cioè chiunque sia in
grado di connettersi) per visualizzare e modificare i dati a proprio
piacimento.
Per semplicità, ci si connette come SYSDBA usando la password
masterkey
. Inoltre, per evitare linee troppo lunghe,
gli esempi saranno su basi di dati locali con percorsi relativi.
Naturalmente si potrà replicare quanto qui appreso in queste sezioni
anche su database remoti, semplicemente fornendo una stringa di
connessione TCP/IP completa.
Firebird ha un programma client a linea di comando che si chiama
isql (Interactive SQL = SQL interattivo). Con
ISQL ci si può connettere in diversi modi ad un database. In uno di
questi, mostrato qui di seguito, si parte in modo interattivo. Si va
nel sottodirettorio bin
della
propria installazione di Firebird, e al prompt dei comandi si digita
isql (Windows) oppure ./isql
(Linux).
[Nei seguenti esempi, ↵
significa
«batti Invio»]
C:\Programmi\Firebird\Firebird_2_0\bin>isql↵ Use CONNECT or CREATE DATABASE to specify a database SQL>CONNECT ..\examples\empbuild\employee.fdb user SYSDBA password masterkey;↵
In isql, ogni comando deve
terminare con un punto e virgola (il carattere
«;
»). Digitanto
Invio senza terminare con punto e virgola, isql
presume che il comando continui nella linea successiva ed il
pronto cambia da SQL>
a
CON>
. Questo permette di spezzare comandi
lunghi su più linee. Dopo un Invio alla fine di
un comando senza il punto e virgola, è sufficiente digitarlo a
linea nuova subito dopo il CON>
e ribattere
Invio.
Su un Classic Server in Linux, si cerca di avere una
connessione veloce e diretta se il percorso al database non
inizia col nome di un host. Questo può fallire se l'utente Linux
non ha sufficienti diritti di accesso al file della base dati.
In tal caso ci si può connettere con
localhost:
<percorso>
cosicchè il processo del server (che con Firebird 2 di solito
opera come utente firebird
) aprirà il file. D'altra
parte, una connessione TCP/IP può fallire se un utente ha creato
il database in modo locale con server Classic ed il server non
ha sufficienti diritti per aprire il file.
Si può anche racchiudere il percorso, il nome utente e/o la
parola chiave fra apici singoli ('
) o doppi
("
). Se il percorso contiene spazi, allora è
obbligatorio racchiuderlo fra apici.
A questo punto, isql dirà che è avvenuta la connessione:
Database: ..\examples\empbuild\employee.fdb, User: sysdba SQL>
Ora si potrà continuare a giochicchiare su
employee.fdb
. Con isql
si possono fare interrogazioni sui dati, avere informazioni sul
metadata, creare altri oggetti del database, lanciare script, ad es.
per la definizione dei dati, e molto altro ancora.
Per uscire e tornare al prompt dei comandi, digitare:
SQL>QUIT;↵
Si può anche digitare EXIT
al posto di
QUIT
, con la differenza che EXIT
applica definitivamente tutte le transazioni pendenti, rendendo
permanenti tutte le eventuali modifiche.
I programmi di utilità GUI (programmi con interfaccia utente in grafica) di solito si fanno carico di comporre la stringa di CONNECT, adoperando le singole informazioni di server, percorso (o alias), nome utente e password introdotte in appositi campi di richiesta. Basta usare tali elementi secondo le linee descritte nei paragrafi precedenti.
Comunemente tali strumenti si aspettano in un'unica stringa l'accoppiata server + percorso/alias – come fa isql.
Ricordarsi che sotto Linux e altre piattaforme «Unix» i nomi sono sensibili al caso del carattere.
Con isql si può creare un database in più di un modo. Qui vedremo al modo più semplice di creare un database in modo interattivo, sebbene per il lavoro serio di gestire il database, si dovrebbero creare e manutenere gli oggetti del database attraverso gli script di definizione dei dati.
Per creare un database interattivamente usando il programma
isql, aprire una finestra a comandi nel
sottodirettorio bin
di Firebird e digitare
isql (su Windows) oppure ./isql
(su Linux):
C:\Program Files\Firebird\Firebird_2_0\bin>isql↵ Use CONNECT or CREATE DATABASE to specify a database
Ora è possibile creare un nuovo database interattivamente.
Supponiamo di volerlo chiamare test.fdb
e di
memorizzarlo nella directory data
del disco D
:
SQL>CREATE DATABASE 'D:\data\test.fdb' page_size 8192↵ CON>user 'SYSDBA' password 'masterkey';↵
Nel comando di CREATE DATABASE è obbligatorio mettere gli apici (singoli o doppi) intorno il percorso, il nome utente e la password. Questo è diverso dal comando CONNECT.
Utilizzando un Classic Server su Linux senza dare il
percorso del database con un nome di host, il server cerca di
creare il database usando per proprietario lo stesso nome utente
dato all'ingresso a Linux. Questo potrebbe essere un effetto non
desiderato (pensate ai diritti di accesso se si desidera che
altri possano connettersi al database). Facendo precedere
localhost:
al
percorso del nome, il processo del server crea e possiede il
file (usualmente Firebird 2 opera come utente firebird
).
Dopo la creazione del database, ci vuole qualche momento, riappare il pronto di SQL. Il database adesso esiste ed è possibile creare alcuni oggetti di prova la suo interno.
Per verificare se effettivamente esiste un database davvero, possiamo digitare e provare questa query:
SQL>SELECT * FROM RDB$RELATIONS;↵
Per quanto non si sia creata ancora nessuna tabella, verrà fuori un bel po' di roba! Questa query infatti mostra tutte le righe della tabella di sistema RDB$RELATIONS, in cui Firebird memorizza il metadata delle tabelle. Un database «vuoto» non è propriamente vuoto: contiene un certo numero di tabelle ed altri oggetti di sistema. Le tabelle di sistema aumentano di dimensione a mano a mano che si aggiungono oggetti al database.
Per tornare al pronto dei comandi, digitare
QUIT
o EXIT
, come spiegato nella
parte per connettersi.
Ogni sistema di gestione delle basi di dati (RDBMS) ha il suo modo personale di implementare SQL. Firebird aderisce allo standard SQL in modo più rigoroso rispetto a molti altri RDBMS. Gli sviluppatori che migrano il codice SQL da prodotti che aderiscono meno allo standard spesso pensano che Firebird si comporti in modo strano o approssimativo, quando invece molte delle sue apparenti stranezze non sono affatto tali.
Firebird supporta lo standard SQL troncando il risultato (in questo caso il quoziente) di un calcolo derivato da
INTERO / INTERO
all'intero immediatamente precedente. Questo può avere conseguenze strane, a meno che non se ne sia a conoscenza.
Per esempio, questo calcolo è corretto per lo standard SQL:
1 / 3 = 0
Se si stà migrando da un sistema RDBMS che risolve tale divisione con un quoziente in virgola mobile, c'è bisogno di modificare ogni espressione coinvolta in modo tale da usare numeri in visgola mobile o scalati per il dividendo o per il divisore, ma anche entrambi.
Per esempio, il calcolo sopra, per non dare un risultato nullo in virgola mobile, dovrebbe essere modificato così:
1.000 / 3 = 0.333
Le stringhe in Firebird sono delimitate da una coppia di
singoli apici (apostrofi o accenti): 'Io sono una
stringa'
(notare: si tratta del codice ASCII 39,
non del 96). Chi ha adoperato una delle
versioni precedenti del parente di Firebird, cioè InterBase®, può
ricordare che si potevano tranquillamente adoperare sia i singoli
che i doppi apici per delimitare le stringhe. Adesso i doppi apici
non possono essere più usati per delimitare le stringhe nelle frasi
SQL di Firebird 2.
Nel caso sia necessario inserire un apostrofo od un accento in una stringa Firebird, si deve «marcarli» facendoli precedere da un altro apostrofo.
Per esempio, questa stringa darebbe un errore:
'Errore d'inserimento'
poichè l'analizzatore incontrerebbe l'apostrofo ed
interpreterebbe che la stringa 'Errore d'
è
seguita dalla parola chiave inserimento
che è
sconosciuta. Per trasformarla in una stringa corretta è necessario
raddoppiare il carattere d'apostrofo:
'Errore d''inserimento'
Notare che si tratta di DUE caratteri di singolo apice, non di un carattere di doppi apici.
In SQL il simbolo di concatenazione delle stringhe è dato da
due caratteri di barra verticale consecutivi senza spazi fra loro:
si tratta del carattere ASCII 124 detto anche simbolo di
«pipe». In SQL, il simbolo «+» è un
operatore solo aritmetico e genera un errore se si cerca di
utilizzarlo per concatenare le stringhe fra loro. Con l'espressione
seguente si fa precedere la stringa «Tradotto da:
» al valore di una colonna che contiene
caratteri:
'Tradotto da: ' || LastName
Firebird 2.0 darà un errore se il risultato di una concatenazione di stringhe ha una lunghezza maggiore a 32Kb, cioè superiore alla massima dimensione di un (var)char. Se solo il risultato potentiale – basato sulla dimensione delle variabili o dei campi – è troppo lungo, si avrà un avviso, ma l'operazione potrà essere completata. Nelle versioni di Firebird precedenti alla 2.0 anche questo avrebbe generato un errore e bloccato l'esecuzione.
Si può vedere più avanti nella sezione Espressioni con valori NULL, cosa succede a concatenare stringhe che
hanno valori a NULL
.
Prima dello standard SQL-92 non era lecito avere nomi di oggetti, cioè identificatori, che duplicassero parole chiave del linguaggio del server, che fossero dipendenti da maiuscole/minuscole oppure che contenessero spazi. Con SQL-92 fu introdotto un nuovo standard per rendere tutto ciò perfettamente lecito, purchè tali identificatori venissero espressi racchiudendoli da una coppia di doppi apici (ASCII 34) ed in seguito, per riferirsi ad essi, si continuasse a delimitarli da una coppia di doppi apici.
Lo scopo di questo bel «regalo» fu quello di semplificare la migrazione del metadata da RDBMS non standard a quelli standard. Il rovescio della medaglia di ciò, è che avendo un identificatore fra doppi apici, si dipende dal modo di scriverlo (maiuscole/minuscole e spazi) ed i doppi apici diventano di conseguenza obbligatori.
Tuttavia Firebird permette una po' di libertà sotto certe limitate condizioni. Se l'identificatore che è stato definito fra doppi apici:
è stato definito tutto maiuscolo,
non è una parola chiave, e
non contiene spazi,
...allora può essere utilizzato in SQL senza apici e senza pensare al caso (maiuscole/minuscole non importa). Tuttavia, nel momento stesso in cui gli si rimettono i doppi apici intorno, bisogna riscriverlo di nuovo tutto maiuscolo!
Attenzione a non fare i furbetti! Ad esempio, se avete due tabelle, una "TABELLAPROVA" ed una "TabellaProva", entrambe definite tra doppi apici, e lanciate il comando :
SQL>select * from TabellaProva;
...avrete i record di "TABELLAPROVA", non di "TabellaProva"!
A meno che non ci sia veramente la necessità estrema di utilizzare identificatori tra doppi apici, usualmente si raccomanda di evitarli e di farne a meno. Firebird accetta tranquillamente identificatori normali e tra doppi apici insieme, pertanto non esiste problema nel migrare, se necessario, quelle parole chiave che si possono ereditare da un altro database.
Alcuni strumenti di amministrazione per database, per default, costringono a mettere fra doppi apici tutti gli identificatori. È bene cercare strumenti di gestione che permettano di mettere i doppi apici in modo opzionale.
In SQL, NULL
non è un valore. È una
condizione o uno stato, di un dato, il cui valore
è sconosciuto. Poichè è sconosciuto, NULL
non può
comportarsi come un valore. Cercando di fare calcoli su
NULL
, o coinvolgerlo con valori di altre
espressioni, il risultato di tali tentativi sarà molto probabilmente
ancora NULL
. Non è zero, né vuoto o una
«stringa vuota» e non si comporta come uno di questi
valori.
Seguono alcuni esempi di quali sorprese si incontrano quando si
provano ad effettuare calcoli e confronti con
NULL
.
Ad esempio, tutte le espressioni seguenti riportano
NULL
:
1 + 2 + 3 +
NULL
not (
NULL
)
'Casa ' || 'dolce ' ||
NULL
Ci si sarebbero aspettati risultati diversi, cioè 6 dalla prima
e «Casa dolce
» dalla terza
espressione, ma, per quanto abbiamo già detto,
NULL
non è il numero 0 o una stringa vuota, è
molto più distruttivo!
La seguente espressione:
Nome || ' ' || Cognome
riporta NULL
se uno o entrambi fra
Nome
e Cognome
è
NULL
. Altrimenti sarà il felice concatenamento
dei due campi con uno spazio in mezzo, anche se uno dei due è una
stringa vuota.
Pensando NULL
come se fosse
SCONOSCIUTO
, presto questi strani risultati
cominciano a prendere senso! Se il valore di
Numero
è sconosciuto, il risultato di '1
+ 2 + 3 + Numero
' sarà altrettanto sconosciuto (e pertanto
NULL
). Se il contenuto di
Stringaccia
è sconosciuto, allora lo sarà il
risultato di Stringaccia || StringaBella
(anche
se StringaBella
non è NULL
).
Eccetera.
Adesso vediamo alcuni esempi di PSQL (SQL Procedurale) con
costrutti if
:
if (a = b) then VariabilePippo = 'Uguali'; else VariabilePippo = 'Diversi';
Eseguendo questo codice, VariabilePippo
sarà 'Diversi'
se entrambi a
e b
sono NULL
. La ragione
è che 'a = b'
riporta NULL
se almeno uno dei due operandi è NULL
. Se
l'espressione di controllo di una frase
«if
» è NULL
,
si comporta come false
: salta il blocco
'then
', ed esegue il blocco
'else
'.
Sebbene l'espressione si comporti
come se fosse false
in questo caso, è ancora
NULL
. Provando ad invertirne il
comporamento con not()
, si otterrebbe un
altro NULL
, e mai
«true
».
if (a <> b) then VariabilePippo = 'Diversi'; else VariabilePippo = 'Uguali';
Bel tentativo! Ma qui, VariabilePippo
sarà 'Uguali'
se a
è
NULL
e b
invece no, o
viceversa. La spiegazione è analoga a quella dell'esempio
precedente.
Firebird 2 implementa un nuovo uso della parola chiave
DISTINCT permettendo di effettuare confronti di
(dis)uguaglianza che tengano conto anche di
NULL
. La semantica è come segue:
Due espressioni sono DISTINCT se
hanno valori diversi o uno dei valori è
NULL
ma l'altro no;
Due espressioni sono NOT DISTINCT se
hanno entrambe lo stesso valore o sono entrambe
NULL
.
Notare che se nessuno degli operandi è
NULL
, DISTINCT funziona
esattamente come l'operatore
«<>
», e NOT
DISTINCT come l'operatore
«=
».
DISTINCT e NOT
DISTINCT riportano sempre true
oppure false
, mai
NULL
.
Usando DISTINCT, si può riscrivere il primo esempio PSQL come segue:
if (a is not distinct from b) then VariabilePippo = 'Uguali'; else VariabilePippo = 'Diversi';
Ed il secondo come:
if (a is distinct from b) then VariabilePippo = 'Diversi'; else VariabilePippo = 'Uguali';
Queste nuove versioni daranno il riisultato che un normale
essere umano (ignaro degli standard SQL) si aspetterebbe, che ci
siano o meno dei NULL
di mezzo.
Molte altre informazioni sui NULL
e sul
loro comportamento può essere trovato nella Guida
Firebird sui Null, in rete a questi indirizzi:
http://www.firebirdsql.org/manual/it/nullguide-it.html (HTML)
http://www.firebirdsql.org/pdfmanual/it/Usare-NULL-in-Firebird.pdf (PDF)
La guida sui NULL è stata molto estesa e aggiornata ancora a Gennaio del 2007.
Firebird Documentation Index → Guida rapida per Firebird 2 → Operare sulle basi di dati |