Sql Server 2005 Davide Mauri Factory Software [email protected] La Piattaforma Applicativa Agenda T-SQL Ranking / Top n CTE Pivot / Unpivot Try … Catch Encryption XML 2 Xml data type XQuery Full Text Search Agenda Integration Services Data e Control Flow Connections Task Transformations Reporting Services 3 Report Manager Sviluppo dei report con Visual Studio Report Builder T-SQL 4 FUNZIONI di RANKING RANK DENSE_RANK NTILE ROW_NUMBER 5 RANK Ritona il “posizionamento” di ogni riga all’interno di una partizione PARTITION BY definisce il criterio di partizionamento ORDER BY stabilisce l’ordine in cui viene appicato il rank alle righe Sintassi: SELECT select_list, RANK() OVER (PARTITION BY col1 ORDER BY col2) as rank FROM Tabella1 6 RANK RANK = 1 + numero di rank che precedono la riga Se due o più righe sono alla pari, ricevono lo stesso rank I rank potrebbero non essere numeri consecutivi 7 DENSE_RANK RANK = 1 + numero di DISTINCT rank che precedono la riga Se due o più righe sono alla pari, ricevono lo stesso rank Non vi sono “gap” nei rank SELECT select_list, DENSE_RANK() OVER (PARTITION BY col1 ORDER BY col2) as rank FROM Tabella1 8 NTILE Distribuisce le righe di una partizione ordinata in uno specificato numero di gruppi Se il numero di righe non è divisibile per il numero di gruppi I gruppi avranno ampiezza differente Prima compariranno i gruppi con più elementi SELECT select_list, NTILE(nr_gruppi) OVER (PARTITION BY col1 ORDER BY col2) as rank FROM Tabella1 9 ROW_NUMBER Ritorna il numero sequenziale di una riga all’interno di una partizione ordinata SELECT select_list, ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) as rank FROM Tabella1 10 TOP 11 Specifica che solo la prima parte di un result set verrà ritornata PERCENT WITH TIES (+ order by) TOP @variabile COMMON TABLE EXPRESSION (CTE) 12 Result set temporaneo Non è salvato come oggetto Rimane in vita solo per la durata della query che lo ospita Migliora la leggibilità e la manutenibilità delle query CTE: Utilizzo Query ricorsive 13 Anchor Member e Recursive Member Quert hint: option (maxrecursion n) Sostituto delle view (quando non serve salvare i metadati) Referenziare lo stesso result set più volte nella query CTE: Sintassi Struttura della CTE: WITH nome_cte [(nome colonna,…)] AS (query che definisce la CTE) Utilizzo: SELECT * FROM nome_cte 14 PIVOT Ruota un’espressione tabellare trasformando i valori univoci di una colonna nelle colonne dell’espressione di output Effettua le aggregazioni che costituiscono l’output SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4 FROM ( SELECT PurchaseOrderID, EmployeeID, VendorID FROM Purchasing.PurchaseOrderHeader )p PIVOT( COUNT (PurchaseOrderID) FOR EmployeeID IN ( [164], [198], [223], [231] )) AS pvt 15 UNPIVOT Effettua l’operazione inversa rispetto a PIVOT Ruota le colonne in righe I valori nulli non possono essere usati SELECT VendorID, Employee, Orders FROM (SELECT VendorID, Emp1, Emp2, Emp3, Emp4 FROM pvt) p UNPIVOT (Orders FOR Employee IN (Emp1, Emp2, Emp3, Emp4, Emp5) )AS unpvt GO 16 Error handling Gestione simile al C# / VB.NET attraverso TRY e CATCH: Se si verifica un errore nel blocco TRY il controllo passa al blocco CATCH. Eseguito il blocco CATCH il controllo passa al codice che sta dopo END CATCH Blocco TRY Exception Blocco CATCH Nessuna Exception 17 Codice Successivo a END CATCH Sintassi di TRY...CATCH 18 Sintassi: BEGIN TRY ... END TRY BEGIN CATCH .... Gestione dell’errore ..... END CATCH Il batch è unico!!!! Try...catch TIPS Ogni TRY..CATCH deve essere contenuto in un unico BATCH, Stored Procedure, Trigger I blocchi TRY…CATCH possono essere nidificati Errori con severity <= 10 sono warning che non vengono intercettati dal blocco CATCH Errori con severity >= 20 che causano l’interruzione della connessione: 19 Non sono gestiti da TRY…CATCH Tuttavia finchè la connessione non è interrotta il blocco CATCH funziona. Try...catch e XACT_STATE Nel blocco catch è bene controllare lo stato della transazione attraverso XACT_STATE() 1: Transazione attiva, la sessione può compiere qualsiasi azione (COMMIT o ROLLBACK) 0: Nessuna transazione attiva -1: Esiste una transazione aperta, ma NON può essere eseguito il COMMIT. BEGIN CATCH IF (XACT_STATE()) = -1 ROLLBACK TRANSACTION; IF (XACT_STATE()) = 1 COMMIT TRANSACTION; END CATCH 20 Informazioni sugli errori ERROR_MESSAGE() ERROR_NUMBER() ERROR_SEVERITY() ERROR_STATE() ERROR_PROCEDURE() ERROR_LINE() Ritornano informazioni solo all’interno di un blocco CATCH. 21 Posso utilizzate una stored procedure per il logging TRY...CATCH: tips Utilizzo di RAISERROR per il rethrow Intercetta: Non intercetta: 22 Deadlock errors Errori di compilazione tipo syntax error Statement level recompilation errors (object name resolution errors) ENCRYPTION Possibilità di criptare i valori tramite l’utilizzo di EncryptKey DecryptKey Utilizzabili negli statement DML Solo chi è in possesso della chiave giusta potrà vedere il valore 23 Gli altri vedranno NULL XML 24 XML in un Database Relazionale? E’ lo standard de facto Dati trasmessi e ricevuti come XML Sempre più utilizzato I database prima o poi devono cominciare a fare i conti con questa realtà 25 Utilizzato come Lingua Franca Allora meglio farlo nel modo migliore XML in un Database Relazionale? XML può vivere all’interno del db in 3 modi 1. TEXT 26 Come accade con Sql Server 2000 Si perdono le funzionalità intrinsche di XML XML in un Database Relazionale? 2. RELATIONAL FORMAT 27 Se possibile un documento può essere scomposto in tabelle Si sfruttano le capacità del motore relazionale Si ottiene tramite OPENXML o XMLBULKLOAD (SqlXml) XML in un Database Relazionale? 3. XML Data Type Utilizzo di tutte le funzionalità di xml Supporto ricerche full-text Supporto validazione Utilizzabile in ogni situazione Attenzione non abusarne 28 Colonne, Parametri, Variabili, Return Value Violazione della forma normale XML in un Database Relazionale? Perchè dovrei?!?! Memorizzazione di documenti XML Memorizzazione di dati destrutturati Sistemi Integrati Messaging (SOAP) Occhio a non sentirsi “obbligati” 29 B2B (Business To Business)/B2C (Business To Consumer) A2A (Application To Application) Ogni tanto la si cerca di usare solo perchè è nuova o perchè non si conoscono alternative XML in un Database Relazionale Una colonna XML può memorizzare well-formed XML 30 Fragments Documents XML in un Database Relazionale Pieno supporto e gestione dell’encoding -- This works correctly INSERT INTO xml_tab VALUES(4, '<?xml version="1.0" encoding="utf-8"?> <doc1> <row au_id="111-11-1111"/> </doc1>') -- This fails, encoding does not agree w/variable type INSERT INTO xml_tab VALUES(5, N'<?xml version="1.0" encoding="utf-8"?> <doc1> <row au_id="111-11-1111"></row> </doc1>') 31 Typed & Untyped XML E’ possibile fare in modo che il tipo XML sia validato da un XML Schema Per validare i dati inseriti Per assicurarsi che tutte le entità abbiano la stessa struttura 32 Definizione dei tipi di dati utilizzati Constrained XML E’ possibile anche utilizzare il vincolo CHECK Constrained XML CREATE TABLE docs ( pk INT PRIMARY KEY, xCol XML not null CONSTRAINT CK_name CHECK (xCol.exist('/book/author[first-name = lastname]') = 0) ) 33 XML Schema Collections Gli XML Schema utilizzati devono essere nel database CREATE XML SCHEMA COLLECTION 34 Il nome verrà utilizzato nell’associazione con il tipo di dato Lo schema deve essere inserito come literal XML Schema Collections literal schema targetNamespace CREATE XML SCHEMA COLLECTION geocoll '<xs:schema ... targetNamespace= urn:geo> ... </xs:schema>' reference to schema collection Memorizzazione nella tabelle di sistema 35 CREATE TABLE Locations ( location xml(geocoll) ... ) sys.xml_schema_collections sys.xml_schema_namespaces XML Schema Sample for namespace urn:geo similar to sql type, structured type, i.e. a tree element that might appear in xml data 36 <xs:schema xmlns:xs= "http://www.w3.org/2001/XMLSchema" targetNamespace="urn:geo" xmlns:tns="urn:geo"> <xs:simpleType name="dim"> <xs:restriction base="xs:int"/> </xs:simpleType> <xs:complexType name="Point"> <xs:sequence> <xs:element name="X" type="tns:dim"/> <xs:element name="Y" type="tns:dim"/> </xs:sequence> </xs:complexType> <xs:element name="Point" type="tns:Point"/> </xs:schema> Utilizzo di Typed XML CREATE TABLE point_tab( id int IDENTITY primary key, -- geocoll include schema for 'urn:geo' namespace thepoint xml(CONTENT, geocoll) GO -- this works, schema-valid Point INSERT INTO point_tab VALUES( '<Point xmlns="urn:geo"><X>10</X><Y>20</Y></Point>') -- this insert fails, value foo is not a dim (integer) INSERT INTO point_tab VALUES( '<Point xmlns="urn:geo"><X>10</X><Y>foo</Y></Point>') 37 XML Schema Collections L’ XML schema non è realmente memorizzato nel database Informazioni non memorizzate 38 Il contenuto è scomposto e memorizzato in tabelle di sistema Solo le imformazioni fondamentali vengono memorizzate Comments, Processing Instructions <xs:annotation> XML Schema Collections Ottenere lo schema memorizzato sys_schema_namespace(…, …) select xml_schema_namespace(N’dbo’, N’geocollection’) Non è lo schema orginale 39 Ma è Functionally Equivalent FOR XML Risultato memorizzabile in una varibile Tramite la keywork TYPE DECLARE @x xml SET @x = SELECT * FROM authors FOR XML AUTO, TYPE Nuova keywork PATH per effettuare lo shaping dell’XML 40 Più semplice da usare che EXPLICIT FOR XML SELECT au_id as [@authorid], au_fname as [name/firstname], au_lname as [name/lastname] FROM authors FOR XML PATH <!– one row per selected row --> <row authorid="111-11-1111"> <name> <firstname>Bob</firstname> <lastname>Smith</lastname> </name> </row> ... 41 XML BULK LOAD 42 I dati XML possono essere popolati tramite BULK LOAD XQuery XQuery è l’evoluzione di XPath Supporto di un subset di XQuery implementazione basata con il draft Novembre 2003 http://www.w3.org/TR/xquery Permette di poter fare query su dati semistrutturati e/o destrutturati 43 Più correttamente è un SuperSet XML XQuery XQuery fatta da “FLWOR” Expressions: Può lavorare direttamente sull’ XML Data Type 44 FOR LET (not supported) WHERE ORDER BY RETURN sia come variabile sia come colonna XQuery Possibilità di utilizzare sia query XPath che FLWOR (: this is a valid XQuery :) /people/person[age > 30] (: so is this FLWOR expression :) for $p in /people/person where $p/age > 30 order by $p/age[1] return $p/name 45 XQuery -- returns <li>moe in record number x</li> -- where x is the ID column, or blank column SELECT xml_col.query(' for $b in //person where $b/@name=“davide" return <li>{ data($b/@name) } in record number {sql:column("xml_tab.id")}</li> ') FROM xml_tab -- returns <li>moe is a stooge</li> DECLARE @occupation VARCHAR(50) SET @occupation = ' is a singer' SELECT xml_col.query(' for $b in //person where $b/@name=“eric" return <li>{ data($b/@name) } {sql:variable("@occupation") }</li> ') FROM xml_tab 46 XQuery & Xml Data Type Xml Data Type Functions exist() value() query() nodes() modify() SELECT xmlCol.query(‘/Root/ProdDesc/*’) FROM myTable 47 xml.exist() xml.exist usa XML type and XQuery expression 48 false se la query restituisce NULL true negli altri casi Può essere utilizzato in constraint di tipo CHECK xml.exist() -- pdoc must have a person element -- as a child of the people root CREATE TABLE xmltab( id INTEGER PRIMARY KEY, pdoc XML CHECK (pdoc.exist('/people/person')=1) ) -- ok insert xmltab values( 1, '<people><person name="bob"/></people>') -- fails, no persons insert xmlpeople values( 2, '<people><emp name="fred"/></people>') 49 Supporto per DEFAULT xml.value() xml.value restituisce un tipo di dato nativo SQL Server e scalar Utilizzo 50 input: XQuery, SQL Type restituisce un tipo scalare o NULL non può restituire un tipo XML predicati (es. WHERE Clause) result values views xml.value() -- insert some rows INSERT xml_tab VALUES('<people><person name=“alessandro"/></people>') INSERT xml_tab VALUES('<people><person name=“davide"/></people>') INSERT xml_tab VALUES('<people><person name=“franco"/></people>') -- this query SELECT id, xml_col.value('/people/person/@name','varchar(50)') AS name FROM xml_tab -- yields this resultset id name -------------------------1 alessandro 2 davide 3 franco 51 xml.query() xml.query resituisce un XML data type input: XQuery l’xml risultante può essere un XML Fragment può costruire nuovi elementi <Invoice> <LineItem>Soda</LineItem> Colonna Invoice, Tabella Invoices <LineItem>Ice</LineItem> </Invoice> SELECT invoice.query('Invoice/LineItem') FROM Invoices <LineItem>Soda</LineItem><LineItem>Ice</LineItem> 52 xml.nodes() scompone il contenuto di un XML data type simile (concettualmente) a value(), ma il risultato può essere application al comando T-SQL CROSS APPLY 53 produce dei nodi, non un valore scalare il risultato è un rowset si ottengono funzionalità simili ad OPENXML performance migliori xml.nodes() --input xml in variable @x <row id=“1”><name>alessandro</name><name>davide</name></row> <row id=“2”><name>franco</name></row> <row id=“3/> -- this query SELECT ... FROM @x.nodes(‘//row’) T(rows) -- yields this resultset id name -------------------------1 alessandro 1 davide 2 franco 54 Using Relational Data in XQuery SQL Server XQuery può utilizzare sia dati XML che dati relazionali sql:variable: accesso a variabili T-SQL sql:column: accesso a columns value 55 limitatamente alla riga in uso Using Relational Data With XML -- returns <li>moe in record number x</li> -- where x is the ID column, or blank column SELECT xml_col.query(' for $b in //person where $b/@name=“Eric" return <li>{ data($b/@name) } in record number {sql:column("xml_tab.id")}</li> ') FROM xml_tab -- returns <li>moe is a stooge</li> DECLARE @occupation VARCHAR(50) SET @occupation = ' is a stooge' SELECT xml_col.query(' for $b in //person where $b/@name=“Bruce" return <li>{ data($b/@name) } {sql:variable("@occupation") }</li> ') FROM xml_tab 56 XQuery DML 57 XQuery DML xml.modify permette la modifica di XML XQuery non ha standard DML vengono utilizzati gli standard proposti insert, delete, replace operators all’interno di espressioni XQuery insert before or after element first or last sibling subelements and attributes replace 58 must be a single node elements or attributes solo simple types “value-of" clause per aggiornare i valori XQuery DML - Original Document declare @x xml set @x = '<Invoice> <InvoiceID>1000</InvoiceID> <CustomerName>Jane Smith</CustomerName> <LineItems> <LineItem> <Sku>134</Sku> <Quantity>10</Quantity> <Description>Chicken Patties</Description> <UnitPrice>9.95</UnitPrice> </LineItem> <LineItem> <Sku>153</Sku> <Quantity>5</Quantity> <Description>Vanilla Ice Cream</Description> <UnitPrice>1.50</UnitPrice> </LineItem> </LineItems> </Invoice>' 59 XQuery DML - Using xml.modify -- use modify to insert a subelement SET @x.modify( 'insert <InvoiceDate>2002-06-15</InvoiceDate> into /Invoice[1] ') -- or insert an attribute SET @x.modify('insert attribute status{"backorder"} into /Invoice[1] ') -- this deletes all LineItem elements SET @x.modify('delete /Invoice/LineItems/LineItem') -- change the value of the CustomerName element SET @x.modify('replace value of /Invoice[1]/CustomerName[1]/text()[1] with "John Smith" ') 60 XML Full Text Search XML filter Index e query su istanze XML Analisi sul contenuto di un token I tag (attributi inclusi) sono rimossi Sintassi — come per le altre colonne CREATE FULLTEXT INDEX ON docs (xDoc) 61 XML Full Text Search Può essere combinata con XQuery Full-text search come filtro, poi XQuery search SELECT R.X.query ('//sec[@num=12]') FROM (SELECT * FROM docs WHERE contains (xDoc, 'Wrd1 Wrd2')) R(X) Supporta l’attributo xml:lang Utilizza correttamente il linguaggio SELECT * FROM docs WHERE contains (xDoc, 'Visionen', LANGUAGE 'German') 62 Integration Services 63 Architettura ed Object Model Separazione dei package in due aree Modello ad oggetti facilmente estendibile basato sul .NET Framework 64 Control Flow Data Flow Non limitato ai soli Custom Task Architettura ed Object Model Supporto per sorgenti e destinazioni multiple Supporto nativo XML, SQL CE 2005, AS 2005 come sorgenti/destinazione dati Introduzione delle DTS Expression 65 Una sorta di linguaggio interno Vagamente simile a C# Ambiente di sviluppo BI Development Studio Praticamente è Visual Studio Designer molto più ordinato tramite l’utilizzo di aree “tematiche” Supporto per sistemi di gestione del codice 66 Visual SourceSafe Migliorate le capacità di debugging Package Elements Numerosi nuovi task Data Flow Data Preparation Workflow Sql Server Scripting Analisys Server Maintenance Aggiunto il supporto per i Containers 67 Loop, For Each, Sequence, ecc… Tools Wizard per: DTExecUI e DTExec Esecuzione dal prompt DTUtil 68 Configurazione dei Package Deployment e Update Migrazione dai DTS di SQL Server 2000 Gestione dal prompt (copy, crypt, sign…) Package Management E’ possibile utilizzare dei Folder per fare ordine Logging non limitato alle trasformazioni 69 Supporto nativo per la configurazione del package senza necessità di utilizzo dell’ambiente di editing Package Checkpointing Sviluppo Molti elementi permettono l’utilizzo di un “Linguaggio” interno: DTS Expressions Possibilità di creare workflow molto complessi Possibilità di gestire gli eventi (es. OnError) Programmabili ed estendibili con .NET 70 Packages 71 Package Content Un Package può contenere: Control Flow Data Flow 72 Task Container Trasformations Connections Configurations Variables Operational Surfaces 73 Control Flow Data Flow Event Handlers Package Explorer Execution Results Connection Managers Properties Control Flow Descrive l’intero processo definito dal Package Organizza i task e specifica percorsi e/o precedenze Il workflow è basato sul risultato di un’espressione DTS 74 Praticamente nessun limite alla fantasia! Data Flow Source Transform Destination Descrive il flusso dei dati (Pipeline) Specifica dettagliatamente tutto ciò che riguarda la manipolazione dei dati E’ un task del Control Flow 75 Connection Managers Le connessioni visualizzate in uno spazio dedicato Non solamente dedicate ai database 76 Es. SMTP Connection Manager, FTP Connection Manager Condivise sia dagli elementi del Control Flow che del Data Flow Control Flow Elements Tre diversi tipi di Container: Possibilità di effettuare dei loop: Raggruppamento di task 77 For Loop ForEach Loop Sequence Control Flow Elements Numerosi nuovi task che evitano la scrittura di codice Data Flow Task File System Task 78 Per la definizione dettagliata dei processi di ETL Per la gestione dei file e delle directory (Create, Copy, Move, Delete, Rename, Set Attributes) Control Flow Elements Script Task Send Mail Task Supporto SMTP (Era Ora! ) FTP Task 79 Esecuzione di script scritti in VB.NET Editor *finalmente* evoluto Supporto per tutte le operazione non solo il GET Control Flow Elements WMI Data Reader Task WMI Event Watcher Task Per monitorare i dati di WMI e rispondere ai cambiamenti XML Task 80 Per ottenere informazioni da WMI Per operare su documenti XML (XSLT, Merge, Patch, Diff, Validate, XPath) Data Flow Elements Conditional Split Transform Multicast Transform Permette di processare una riga più volte e con diversi meccanismi Union All Transform 81 Per processare una riga secondo diversi criteri Prende più input e di generare un solo output Data Flow Elements Sort Transformation Count Rows Transformation Per contare le righe Derived Column 82 Per ordinare le righe Per modificare o creare colonne Data Flow Elements Fuzzy Grouping Fuzzy Lookup Pulisce ulteriormente i dati (Es. Standardizzazione, Correzione ed inserimento valori mancanti) Percentage Sampling 83 Pulisce e standardizza i dati (Es. Rimuove i duplicati) Crea dati di prova Data Viewers Attivi durante il debug Permettono di interrompere l’esecuzione di un Data Flow visualizzare i dati E’ possibile vedere anche la distribuzione dei dati con l’ausilio di grafici 84 Reporting Services 85 Reporting Services Editor Report: BI Dev. Studio Non è obbligatorio in quanto il report è un file xml Però è praticamente indispensabile Creare un progetto di tipo “Report Project” Aggiungere: 86 Data Sources Parametri Reports Reporting Services Ogni proprietà visibile (e non) può essere modificata tramite l’uso di expressions Il linguaggio è VB.NET In più ci sono funzioni aggiunte dall’infrastruttura di SSRS 87 Previous RowNumber CountRows Sviluppo E’ possibile aggiungere funzioni tramite Per personalizzare il report è possibile utilizzare immagini 88 Codice Embedded (VB.NET) External Assembly (Qualsiasi linguaggio .NET) Memorizzate nel report (embedded) Esterne (link) Memorizzata in un db Reporting Services Il Report Manager è “solamente” l’applicazione di default fornita da Microsoft Utilizza il web service per visualizzare i metadati e gestire i report I report vengono visualizzati in un IFRAME 89 E sono chiamati tramite URL Reporting Services E’ possibile integrare SSRS in qualsiasi applicazione tramite E’ possibile integrare il tutto con SharePoint 90 Chiamate SOAP (Web Services) Chiamate via URL Web part disponibile dalla SP2 dei “vecchi” RS Reporting Services Creazione di report ad-hoc Non c’è un liberta “totale” 91 Tramite il Report Builder I report possono essere creati sulla base di un “Report Model” Il “Report Model” contiene i metadati disponibili Più che sufficiente nel 99% dei casi Il “Report Model” si crea da Visual Studio Reporting Services 92 Invocazione di Report E’ possibile accedere a Reporting Services in una soluzione custom in due modalita’: Url access Web Services 93 richiesta via HTTP/GET Richiesta via SOAP Invocazione di Report 94 Invocazione di Report Url Access Report Server URL Report Name Nome del report Report Parameters 95 Defaults to http://[servername]/ReportServer I nomi devono mappare I parametri definiti nel report Es http://servername/ReportServer/ReportName? CategoryID=1&EmployeeID=1 Invocazione di Report Web Services Esecuzione dei report Gestione report 96 GetReportParameters() Render() Anche asincrona CreateReport() GetReportDefinition() Distribuzione dei report I report possono essere visualizzati …ma possono anche essere loro ad andare dall’interessato 97 Da web, tramite il Report Manager Da applicazioni ad hoc, o integrati in applicazioni esistenti Via mail Via network share Questa funzionalità prendere il nome di Subscription Distribuzione dei report Le subscription vengono eseguite in base ad una schedulazione La schedulazione fa affidamento sul SQL Server Agent 98 Ad hoc Condivisa Quindi deve essere attivo! Vengono creati dei Job ad hoc Distribuzione dei report 99 Distribuzione tramite network share Distribuzione dei report 100 Distribuzione via email Distribuzione dei report Le sottoscrizioni guidate (Data-Driven subscription) permettono di impostare a runtime I dati vengono prelevati tramite query ad hoc 101 Destinatari Parametri Formati La sorgente dati, come al solito, può essere qualsiasi cosa (SQL Server, Oracle, OLEDB, ODBC) Domande ? 102 © 2004 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.