L'introduzione di un tipo dati nativo per l'XML ha rivoluzionato le istruzioni T-SQL di SQL Server 2005. In questo articolo illustremo i nuovi comandi DDL per la gestione degli Schema XSD in SQL Server 2005.
Schemi XML e W3C Infoset Model
Prima di iniziare la discussione è bene fare chiarezza su un punto. L'uso sempre maggiore di XML come supporto di memorizzazione (per dati strutturati e non) e nello lo scambio di informazioni ha spinto il Consorzio W3C a rilasciare un nuovo insieme di raccomandazioni per l'XML, denominate XML Infoset Model in grado di prendere in considerazione la natura dei dati (il valore "25" è memorizzato come stringa ma è anche un numero!) all'interno di elementi e attributi del documento XML.
Di qui la necessità di avere Schemi XML o XSD in grado di descrivere con precisione i tipi di dati presenti in un documento XML e quindi il suo grado di tipizzazione. SQL Server 2005 per aderire al modello proposto dal W3C incorpora un repository di schema xml da utilizzare nella validazione delle istanze di dati XML archiviate nei suoi database.
Le novità T-SQL per il supporto agli Schema XSD
La gestione degli Schema XSD è stata concepita con l'introduzione di nuove istruzioni nel DDL tramite le quali è possibile aggiungere, modificare ed eliminare gli schemi.
Per supportare queste operazioni SQL Server ragiona in termini di Collezione di Schema. Una collezione è "un contenitore di schema XSD" ed un database può averne diverse al suo interno. Ciascuna collezione può contenere uno o più Schema XSD identificati a loro volta da namespaces.
Durante la creazione di una collezione gli schemi XSD aggiunti vengono importati automaticamente all'interno della stessa in attesa di essere associati a colonne o variabili XML.
Tutte le collezioni di un database, una volta importate, vengono memorizzate in tabelle di sistema e quindi fruibili come metadati. Una collezione di schema è paragonabile a un qualsiasi oggetto di SQL Server; può essere creata, rinominata, eliminata e messa in sicurezza (GRANT, DENY e REVOKE).
Creare collezioni di schema XSD
Vediamo come creare una nuova collezione di schema.
Listato 1. Sintassi T-SQL per creare una collezione di schema xml
CREATE XML SCHEMA COLLECTION [ <relational_schema>. ]sql_identifier AS Expression
Dove:
- relational_schema identifica lo schema relazionale. Può essere omesso, ed in questo caso viene usato quello predefinito (dbo tipicamente).
- sql_identifier identifica il nome vero e proprio dello schema.
- expression è una costante o variabile (di tipo varchar, varbinary, nvarchar, nvarbinary o xml) che identifica il contenuto dello schema.
Non dobbiamo confondere lo schema relazionale con lo schema XSD. Gli schemi relazionali sono contenitori per oggetti del database come tabelle, procedure, etc. e sono posseduti da utenti o ruoli del database (maggiori informazioni sulla documentazione online di SQL Server).
Supponiamo di voler creare lo schema SchemaDettagliOrdine
(il quale contiene informazioni per descrivere un ordine creato da un sistema di ecommerce):
Listato 2. Codice T-SQL per la creazione di una collezione di schema xml
-- possiamo usare lo schema relazionale predefinito
CREATE XML SCHEMA COLLECTION dbo.SchemaDettagliOrdine AS 'CONTENUTO SCHEMA'
-- oppure uno schema relazionale ad hoc
CREATE XML SCHEMA COLLECTION Vendite.SchemaDettagliOrdine AS 'CONTENUTO SCHEMA'
Importazione degli schema nelle collezioni
Cosa succede quando viene aggiunto uno schema ad una collezione? Al riguardo bisogna fare alcune precisazioni.
- SQL Server non importa totalmente lo schema, ma solamente alcune parti (o componenti) di esso.
- Ognuna di queste viene poi salvata su alcune tabelle di sistema (tra cui la tabella
sys.xml_schema_components
). - I componenti dello schema XSD archiviati appartengono a:
- Elementi
- Attributi
- Definizione dei tipi
- Ogni componente estratto dallo schema XSD viene poi incluso in una delle seguenti categorie:
- ATTRIBUTE
- ELEMENT
- TYPE (per tipi semplici o complessi)
- ATTRIBUTE GROUP
- MODELGROUP
Quindi, solo i componenti e non lo schema XSD nella sua integrità, vengono considerati ai fini della validazione delle istanze di dati XML in colonne o variabili XML.
I namespaces
Tra i vari elementi estratti da uno schema in fase di importazione meritano una menzione speciale i namespaces. SQL Server durante l'importazione di uno schema XSD memorizza i namespaces del documento in una tabella di sistema denominata sys.xml_schema_namespaces
.
Il contenuto della tabella sys.xml_schema_namespaces
, dove sono presenti i namespaces delle collezioni di schema XML del database corrente, induce ad alcune considerazioni:
- Ogni database possiede una collezione di schema predefinita denominata sys (con id pari a 1) la quale contiene i namespaces essenziali per lavorare con i dati XML.
- Una collezione può contenere schemi XSD senza alcun namespace.
- Se uno schema XSD contiene più namespaces viene memorizzato solo il namespace predefinito.
I namespaces servono a SQL Server per identificare i singoli schema presenti nella collezione.
Esempi concreti per la creazione di collezioni di schema
Ci sono vari modi per creare una collezione tramite l'istruzione CREATE XML SCHEMA COLLECTION
, principalmente:
- Passare il contenuto dello schema come testo alla CREATE dopo la parola chiave AS.
- Assegnare lo schema ad una variabile xml e successivamente passare quest'ultima alla CREATE dopo la parola chiave AS.
La seconda opzione è particolarmente utile qualora sia necessario caricare gli schema dal disco fisso del PC, ciò viene fatto in combinazione con l'uso di OPENROWSET
.
Listato 3. Codice T-SQL per il caricamento bulk di uno schema XSD
DECLARE @schemapersona XML
SELECT @schemapersona = xmlDaFile FROM
OPENROWSET(Bulk 'e:SchemasPersona.xsd', SINGLE_CLOB) as results(xmlDaFile)
CREATE XML SCHEMA COLLECTION SchemaPersona AS @schemapersona
Ancora più interessante è unire il contenuto di più files alfine di ottenere un'unica collezione.
Listato 4. Codice T-SQL per il caricamento bulk con concatenazione di più schema XSD
DECLARE @schema1,@schema2 XML
SELECT @schema1= xmlDaFile FROM
OPENROWSET(Bulk 'e:SchemasPersona.xsd', SINGLE_CLOB) as results(xmlDaFile)
SELECT @schema2 = xmlDaFile FROM
OPENROWSET(Bulk 'e:SchemasPersonaOccupazione.xsd', SINGLE_CLOB) as results(xmlDaFile)
-- Uniamo il contenuto delle due variabili (quindi file) xml
DECLARE @schemapersona XML
SET @schemapersona = CONVERT( XML, CONVERT(nvarchar(MAX), @schema1) + CONVERT(nvarchar(MAX), @schema2) )
CREATE XML SCHEMA COLLECTION SchemaPersona AS @schemapersona
Per creare collezioni di schema possiamo anche passare il contenuto della schema in modo testuale al comando CREATE XML SCHEMA COLLECTION
.
Listato 5. Creazione di una collezione composta da un solo schema XSD senza namespaces associati.
CREATE XML SCHEMA COLLECTION [dbo].[SchemaPersona] AS
N'
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="NomeCompleto" type="xsd:string"/>
</xsd:schema>
'
Listato 6. Creare una collezione composta da due schemi XSD uno con e l'altro senza namespaces
CREATE XML SCHEMA COLLECTION [dbo].[SchemaPersona] AS
N'
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="NomeCompleto" type="xsd:string"/>
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://html.it/Occupazione">
<xsd:element name="Occupazione" type="xsd:string"/>
</xsd:schema>
'
Se i componenti che vogliamo aggiungere alla collezione fanno riferimento a componenti già presenti nella collezione stessa, allora è necessario utilizzare la direttiva
. Nel caso del listato 7 il namespace http://html.it/PersonaTipi contiene le definizioni dei tipi utilizzate nello schema con namespace http://html.it/Persona.
Listato 7. Creazione di una collezione composta da due schemi XSD con namespaces associati e con uso di import.
CREATE XML SCHEMA COLLECTION [dbo].[SchemaPersona] AS
N'
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://html.it/PersonaTipi">
<xsd:simpleType name="nome">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="60"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>v
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://html.it/Persona" xmlns:tipi="http://html.it/PersonaTipi">
<xsd:import namespace="http://html.it/PersonaTipi"/>
<xsd:element name="nomeCompleto" type="tipi:nome"/>
</xsd:schema>
'