Autore: Francesco Quaratino
Sql Server 2005 introduce il tipo di
dato nativo XML per trattare documenti e frammenti XML, insieme a metodi
specifici per interrogare e modificarne il contenuto. XQuery è il linguaggio
implementato per le interrogazione dei dati XML attraverso i nuovi metodi di
interrogazione. XML (eXtensible Markup Language) ha rappresentato di fatto una
rivoluzione nel concetto di rappresentazione e di scambio dei dati (vedi Riquadro 1).
A suggerirne l’utilizzo negli ambiti più disparati
dell’informatica sono le sue preziose capacità intrinseche, come quella di
astrarre il contenuto di un documento dalla sua presentazione, essere
autodescrittivo, semplificare la condivisione dei dati tra piattaforme
indipendenti, essere leggibile dall’uomo e usare una struttura gerarchica di
archiviazione dei dati. In particolare, il fatto di essere un formato di dati
auto-descrittivo implica la possibilità di descrivere il medesimo dato con
attributi diversi: in altre parole, un dato caratterizzato da attributi
variabili, ciò che si intende per dato semi-strutturato (semi-structured
data) o destrutturato.
Poiché tale possibilità è sconosciuta al modello di dati
relazionale, è proprio questo particolare aspetto dell’XML che mette in luce il
vantaggio maggiore di avere un supporto XML o, ancor meglio, un tipo di dato
nativo XML in un database relazionale puro come Sql Server. A questo proposito,
è bene tenere presente la distinzione fondamentale che esiste tra database
nativi XML (NDX) e database relazionali con supporto XML (XED), basata sul
motore di persistenza dei dati [1][2]: in un database NDX il documento
XML costituisce l’unità fondamentale di persistenza, mentre in un XED la
persistenza continua ad essere affidata ad un motore relazionale oppure object
oriented. Il consorzio XML:DB Iniziative [3], che si occupa della
definizione di una API standard per la gestione dei database XML, ha definito i
seguenti requisiti fondamentali per un database nativo XML (NDX):
1. deve presentare un modello logico per la gestione dei
documenti XML e fornire strumenti, conformi a tale modello, per memorizzare ed
interrogare questi documenti. Il database può implementare un proprio modello
oppure adottare uno di quelli disponibili come quelli utilizzati da XPath o XML
Infoset;
2. deve avere come unità fondamentale di memorizzazione
il documento XML, allo stesso modo in cui la tabella è l’unità di base nei
database relazionali;
3. deve essere indipendente dal modello fisico di
storage.
In un’accezione più ampia, invece, possono essere considerati
database XML quei database che, pur non offrendo un tipo di persistenza del
dato XML, espongono metodi di accesso tipici della tecnologia XML (XPath,
XQuery, DOM). Sql Server 2005 migliora il supporto XML precedentemente offerto
da Sql Server 2000 introducendo il tipo di dato nativo XML e metodi di accesso
ai dati XML, proponendo un modello già da tempo consolidato nel DBMS Oracle –
rivale di sempre e oggi più che mai.

Passato e presente di XML in Sql Server
Sql Server 2000 non aveva un tipo di dato nativo XML. Si
sopperiva a questa mancanza con l’uso di campi di tipo TEXT oppure con la
memorizzazione in formato relazionale (sempre che la struttura del documento
XML fosse sufficientemente semplice da rendere possibile la memorizzazione del
documento in tabelle normalizzate) [1]. Usare campi di tipo TEXT
inibisce la possibilità di usare un linguaggio di query (XPath) sul documento
salvato, e con essa tutte le potenzialità che XML è in grado di esprimere,
mentre la memorizzazione in formato relazionale costringe a una sorta di
conversione che implica un notevole lavoro e, comunque, fa perdere la capacità
gerarchica di lavorare con XML.
Con Sql Server 2005 si possono memorizzare documenti o
frammenti XML in un tipo di dato nativo XML (un frammento è un documento XML
privo di una elemento radice). Ciò permette di creare tabelle che registrino
solo dati XML o dati XML insieme a dati relazionali, validare dati XML
attraverso gli schema, creare indici sui dati XML, interrogare e modificare
dati con XQuery, combinare i metodi di interrogazione dei dati XML con query
standard T-Sql per scrivere query che restituiscano dati relazionali insieme a
dati XML. Ecco come creare un campo di tipo XML:
CREATE TABLE xml_tab ( id INT
PRIMARY KEY, xml_col XML ) GO
Alla stregua di un
campo tradizionale del modello relazionale, per il campo XML si può specificare
se ammette valore NULL o meno, fornire un valore di default, e definire un
vincolo CHECK. Nell’esempio seguente viene creato un vincolo CHECK sul campo di
tipo XML che verifica l’esistenza dell’elemento titolo. I metodi XML (di
cui parleremo dopo) devono essere forniti attraverso una user-defined function:
CREATE
FUNCTION udf_check_xml (@xml_col XML)
RETURNS bit
AS
BEGIN
RETURN
(
SELECT (@xml_col.exist('//titolo'))
)
END
GO
CREATE TABLE xml_tab
(
id INT PRIMARY KEY,
xml_col XML NOT NULL DEFAULT('')
CONSTRAINT CK_name CHECK
(dbo.udf_check_xml (xml_col) = 1)
)
GO
Nel campo xml_col si può inserire un documento o frammento
XML well-formed (vedi Riquadro 2), in caso contrario l’istruzione
di inserimento/aggiornamento fallisce:
INSERT INTO
xml_tab VALUES(1, '')
INSERT INTO xml_tab VALUES(2, N'')
--fallisce perché il frammento XML inserito non è well-formed
INSERT INTO xml_tab VALUES(3, '')
--fallisce perché viola il CHECK CONSTRAINT
INSERT INTO xml_tab VALUES(4, '')
Il dato XML è registrato internamente in un formato binario
compresso per consentire un parsing più veloce rispetto ad una rappresentazione
testuale. Quando il dato viene usato, è convertito in Varchar unicode (UTF-16).
Per determinare la dimensione in byte effettiva di un dato XML si può valutare
la funzione DATALENGTH():
SELECT
DATALENGTH (xml_col) FROM xml_tab
Il tipo di dato XML può essere adoperato oltre che per
creare campi di tabella, anche per definire variabili e parametri di input e
output di stored procedure e user-defined function.
CREATE
PROCEDURE sp_xml ( @x XML, @y XML OUTPUT)
AS
...
CREATE FUNCTION fn_xml ( @x NVARCHAR(max))
RETURNS XML
AS
DECLARE @a XML SET @a = @x
...
RETURN @a
![Riquadro 2]()

Metodi del tipo di dato XML
Per interrogare un dato XML estraendo un frammento o l’intero
documento XML, è possibile usare metodi esposti dal dato XML, i quali accettano
come parametro di input un’espressione XQuery. XQuery 1.0 è un linguaggio di
interrogazione standard di dati XML definito dal Wide Web Consortium (W3C) e
basato su XPath 2.0, un linguaggio di navigazione che usa una sintassi
path-based per l’identificazione dei nodi di un documento XML. XQuery è un
linguaggio dichiarativo, tipizzato e funzionale, e trattasi, fondamentalmente,
di un’estensione (superset) di XPath 2.0.
Sql Server 2005 supporta un sottoinsieme di XQuery 1.0 basato
sul draft di Novembre 2003 [4]. I metodi applicabili sul dato XML sono i
seguenti: exist(), query(), value(), nodes() e modify().
Il metodo exist() permette di valutare l’esistenza di elementi o
attributi nelle clausole WHERE o nei CHECK CONSTRAINT, e restituisce il valore
1 se la valutazione ha esito positivo, oppure 0 (zero) in caso di esito
negativo. Di seguito, un esempio che fa uso di exist() nella clausola
WHERE di una SELECT, allo scopo di selezionare le righe che presentano nel
campo XML denominato xml_col il valore “Infomedia” in un qualsiasi
attributo (@*) dell’elemento “editore”, indipendentemente dalla posizione (//)
di quest’ultimo nel dato XML.
SELECT
*
FROM
xml_tab
WHERE
xml_col.exist('//editore[@*="Infomedia"]') = 1
Il metodo query() restituisce un untyped XML
(documento o frammento), come risultato della valutazione dell’espressione
XQuery su una lista di nodi XML. Il metodo value() restituisce un dato
scalare convertito nel tipo di dato T-SQL specificato come secondo argomento
della funzione. Di seguito due esempi che fanno uso di value() prima
nella SELECT e poi nella clausola WHERE.
SELECT
xml_col.value('/libro[1]/autore[1]', 'varchar(50)')
FROM
xml_tab
SELECT
*
FROM
xml_tab
WHERE
xml_col.value('/libro[1]/autore[1]', 'varchar(50)') =
'F.Quaratino'
Il metodo nodes() scompone il contenuto di un tipo di
dato XML restituendo ogni elemento su una riga diversa. Poiché XQuery non
definisce una sintassi per la modifica dei documenti XML, Microsoft ha
sviluppato un proprio XML Data Modification Language (DML) (6) utilizzabile dal
metodo modify(), il quale consente la modifica del dato XML accettando
come parametro di input un’istruzione XML DML di inserimento (insert),
cancellazione (delete) o sostituzione (replace value of).
Gli indici XML
La natura destrutturata di un dato XML determina un
inconveniente non irrilevante per un database: una gestione fondamentalmente
lenta del dato. Da qui la necessità di creare degli indici su un campo di tipo
XML. Sql Server 2005 prevede la creazione di un indice primario e fino a 248 indici
secondari, a patto che esista un indice primario (clustered) sulla chiave
primaria della tabella. L’indice primario XML indicizza tutti i tag, i valori e
i percorsi del contenuto di un campo XML. La chiave primaria è usata per
correlare le righe dell’indice XML con le righe della tabella di database di
cui fa parte il campo stesso. Di seguito l’istruzione T-SQL di creazione
dell’indice XML primario sul campo xml_col della tabella xml_tab
CREATE
PRIMARY XML INDEX xml_idx on xml_tab (xml_col) GO
Dopo aver creato un indice primario sulla colonna XML, è
possibile creare indici XML secondari per velocizzare particolari tipi di
query. Sono disponibili tre tipi di indici XML secondari: PATH, PROPERTY e
VALUE: - PATH per le ricerche di valori quando si conosca l’esatto percorso
dell’elemento o attributo da cercare (per esempio: SELECT * FROM xml_tab WHERE
xml_col.exist ('/libero[@anno = "2005"]') = 1) - VALUE per le
ricerche di valori quando non si conosca il nome o l’esatto percorso
dell’elemento o dell’attributo che contiene tale valore ( è il caso delle
cosiddette query “wildcard" come: /libro [@* = "poesie"], in cui
la query cerca ogni elemento che abbia un qualsiasi attributo che abbia il
valore "poesia" oppure ('//libro/@genere[. = "poesia"]') = 1 in cui viene fornito un path
parziale attraverso //) - PROPERTY per le ricerche di valori specificando il
nome di un elemento(/libro/autore) Ecco la sintassi per la creazione di indici
XML secondari:
CREATE XML
INDEX on () USING XML INDEX FOR [PATH | VALUE | PROPERTY]
Conclusioni
Combinare dati relazionali con dati XML, offre nuove e
interessanti possibilità nella modellazione dei dati, in grado di avvicinarsi
maggiormente al mondo reale sempre suscettibile di cambiamenti. L’introduzione
di un tipo di dato nativo XML consentirà anche ai progettisti di database che
adoperano Sql Server, di progettare applicazioni molto più flessibili, in
quanto capaci di assorbire meglio i cambiamenti che intervengono nel dominio
applicativo dell’applicazione, nel corso del suo intero ciclo di vita, grazie
alla possibilità di modellare i dati destrutturati. Occorre però fare
attenzione a non farne un uso spregiudicato, dettato dalla moda del momento o
dalla voglia di provare ad ogni costo il nuovo giocattolo messo a disposizione
dalla tecnologia emergente. Sarà, quindi, buona norma continuare ad usare il
modello relazionale per la maggior parte dei dati, introducendo campi XML per
ospitare informazioni non obbligatorie o che potrebbero cambiare col tempo.
Bibliografia e Riferimenti
(1) G. Veneri – “DB e XML:
prodotti”, Computer Programming/Infomedia, Maggio 2005
(2) M. Simi – “Database XML nativi”, Computer Programming/Infomedia,
Maggio 2005
(3) XML:DB Initiative – http://xmldb-org.sourceforge.net
(4) http://www.w3.org/TR/xquery
(5) M. Nunn – “Extending XML in SQL Server 2005”, Sql Server
Magazine/Penton, June 2005
(6) P.Vithanala – “Introduction to XQuery in SQL Server 2005”, Microsoft
Corporation, June 2005
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/sql2k5_xqueryintro.asp
(7) S. Pal et al. – “XML Best Practices for Microsoft SQL Server 2005”, Microsoft
Corporation, April 2004 http://msdn.microsoft.com/SQL/archive/default.aspx?pull=/library/en-us/dnsql90/html/sql25xmlbp.asp
(8) S. Pal et al. – “XML Support in Microsoft SQL Server 2005”, Microsoft
Corporation, May 2005 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/sql2k5xml.asp

L'articolo è stato precedentemente pubblicato anche su Xplayn.org