xplayn > share your experience     
RSS Feed Login     Password        » Registrati «
  
          Home
  Team & Mission
          News
  Development
  Database
          Pubblicazioni
  Articoli
  Tips
  IMHO
          Risorse
  Guide/Manuali/Tools
  Glossario SQLServer
  Collabora con noi
          Blogs
  Maurizio Tammacco
  Francesco Quaratino
  Renzo Pampani
          Formazione
  Database
 
                Partners
      http://www.dotnetside.org
 
 
Pubblicazioni »
Supporto XML in SQL Server 2005
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.

Riquadro 1


[ 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
 

Nota: l'articolo è stato precedentemente pubblicato sul N. 65 di Visual Basic Journal (Sett/Ott '05)
 
Autore E-Mail Web Site Data
Francesco Quaratino francesco_AT_xplayn.org www.xplayn.org 29/01/2006
      ©Copyright 2005 - xplayn.org