1、XML
xml数据可以组成为多个属性,或者多个项目
CREATE DATABASE Test USE TEST GO drop table dbo.book create table dbo.book (BookID int identity(1,1) primary key, BookNM char(100) not null, AuthorID int not null, ChapterDESC XML null ) go --1.非类型化XML declare @book xml set @book = CAST('<book name="sql server 2000 fast answers"> <chapters> <chapter id="1">Installation,Upgrades...</chapter> <chapter id="2">Configuring SQL Server</chapter> <chapter id="3">Creating and Configuring Databases</chapter> <chapter id="">SQL Server Agent and SQL Logs</chapter> </chapters> </book>' as XML ) insert into dbo.book(BOOKNM,AUTHORID,CHAPTERDESC) values('sql server', 55, @book) --2.创建XML架构 CREATE XML SCHEMA COLLECTION BOOKSTORECOLLECTION AS N'<xsd:schema targetNamespace="http://ggg/bookstore" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified"> <xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" /> <xsd:element name="bookxml"> <xsd:complexType> <xsd:sequence> <xsd:element name="bookname" minOccurs="0"> <xsd:simpleType> <xsd:restriction base="sqltypes:varchar"> <xsd:maxLength value="50" /> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="ChapterID" type="sqltypes:int" minOccurs="0" /> <xsd:element name="ChapterNM" minOccurs="0"> <xsd:simpleType> <xsd:restriction base="sqltypes:varchar"> <xsd:maxLength value="50" /> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> ' --3.类型化xml create table dbo.bookXML (BookID int identity(1,1) primary key, BookNM char(100) not null, ChapterID int not null, ChapterDESC XML (bookStoreCollection) null --类型化xml ) declare @bookxml xml(bookstorecollection) set @bookxml ='<bookxml xmlns="http://ggg/bookstore" > <bookname>sql</bookname> <ChapterID>123</ChapterID> <ChapterNM>sqlwc</ChapterNM> </bookxml> ' insert into bookXML(BookNM,ChapterID,ChapterDESC) values('sql server 2008',123,@bookxml) select * from bookXML --4.1查看xml架构 select * from SYS.xml_schema_collections --4.2查看命名空间 select n.*, c.* from sys.xml_schema_namespaces n inner join sys.xml_schema_collections c on n.xml_collection_id = c.xml_collection_id --4.3删除xml架构 drop xml schema collection bookstorecollection
获取数据
create table dbo.bookInvoice (bookInvoiceID int identity(1,1) primary key, bookinvoiceXML xml not null) insert into bookInvoice(bookinvoiceXML) values('<bookinvoice invoicenumber="1" customerid="22" orderdate="2008-07-01"> <orderitems> <item id="22" qty="1" name="sql fun in the sun" /> <item id="24" qty="1" name="t-sql crossword puzzles" /> </orderitems> </bookinvoice>') insert into bookInvoice(bookinvoiceXML) values('<bookinvoice invoicenumber="1" customerid="40" orderdate="2008-07-11"> <orderitems> <item id="11" qty="1" name="MCDBA Cliff Notes" /> </orderitems> </bookinvoice>') insert into bookInvoice(bookinvoiceXML) values('<bookinvoice invoicenumber="1" customerid="9" orderdate="2008-07-22"> <orderitems> <item id="11" qty="1" name="MCDBA Cliff Notes" /> <item id="24" qty="1" name="t-sql crossword puzzles" /> </orderitems> </bookinvoice>') --exist方法 select bookInvoiceID from dbo.bookInvoice where bookinvoiceXML.exist( '/bookinvoice/orderitems/item[@id=11]') = 1 --nodes方法、value方法 declare @bookxml xml select @bookxml = bookinvoiceXML From dbo.bookInvoice where bookInvoiceID = 1 select bookId.value('@id','integer') from @bookxml.nodes( '/bookinvoice/orderitems/item') as booktable(BookID) --query方法 declare @v xml select @v = bookinvoiceXML from dbo.bookInvoice where bookInvoiceID = 1 select @v.query('/bookinvoice/orderitems') --value方法,一次只能处理一个值,所以这里加了[1]来限制只取返回结果集的第一行 --[2]限制只取返回结果集的第二行 select bookinvoicexml.value( '(/bookinvoice/orderitems/item/@name)[1]', 'varchar(30)') as titles from dbo.bookInvoice union select bookinvoicexml.value( '(/bookinvoice/orderitems/item/@name)[2]', 'varchar(30)') from dbo.bookInvoice
修改数据
--通过modify方法插入一geitem update dbo.book set ChapterDESC.modify ('insert <chapter id="5">SQL SERVER INTERNALS</chapter> into (/book/chapters)[1]') select * from dbo.book
建立XML索引
可以使用xml索引提高xml数据类型列的查询性能,表 必须已经在主键上定义了聚集索引。xml列只能建立一个主xml索引,以及最多3个辅助。
Create XML Index CREATE [ PRIMARY ] XML INDEX index_name ON <object> ( xml_column_name ) [ USING XML INDEX xml_index_name [ FOR { VALUE | PATH | PROPERTY } ] ] [ WITH ( <xml_index_option> [ ,...n ] ) ] [ ; ] <object> ::= { [ database_name. [ schema_name ] . | schema_name. ] table_name } <xml_index_option> ::= { PAD_INDEX = { ON | OFF } | FILLFACTOR = fillfactor | SORT_IN_TEMPDB = { ON | OFF } | IGNORE_DUP_KEY = OFF | DROP_EXISTING = { ON | OFF } | ONLINE = OFF | ALLOW_ROW_LOCKS = { ON | OFF } | ALLOW_PAGE_LOCKS = { ON | OFF } | MAXDOP = max_degree_of_parallelism }
--1.建立主xml索引 create primary xml index idx_xml_primary_book_ChapterDesc on dbo.book(ChapterDesc) /*======================================================= 2.建立辅助xml索引,下面的参数用于辅助索引,和xquery优化相关: A.value辅助索引用于根据模糊路径创建索引。 B.path辅助索引根据路径和节点值创建索引。 C.property辅助索引根据某个路径查询节点值,来创建索引 ========================================================*/ create xml index idx_xml_value_book_ChapterDesc on dbo.book(ChapterDesc) using xml index idx_xml_primary_book_ChapterDesc for value --3.查看xml索引元数据 select * from sys.xml_indexes select * from sys.indexes where name in ('idx_xml_primary_book_ChapterDesc', 'idx_xml_value_book_ChapterDesc')
在xml文档与关系型数据之间进行转换
--1.把关系型数据格式化为xml /*=============================================== <shifts> <shift OBJECT_ID="3" name="sysrscols" /> <shift OBJECT_ID="5" name="sysrowsets" /> <shift OBJECT_ID="7" name="sysallocunits" /> <shift OBJECT_ID="8" name="sysfiles1" /> <shift OBJECT_ID="17" name="syspriorities" /> <shift OBJECT_ID="19" name="sysfgfrag" /> <shift OBJECT_ID="23" name="sysphfg" /> <shift OBJECT_ID="24" name="sysprufiles" /> </shifts> =================================================*/ select top 8 OBJECT_ID, --属性 name --属性 from sys.objects for xml raw('shift'), --item root('shifts'), --根 type /*=============================================== <o object_id="37575172"> <t name="wcObjects"> <c name="name" /> <c name="object_id" /> <c name="principal_id" /> <c name="schema_id" /> <c name="parent_object_id" /> <c name="type" /> <c name="type_desc" /> <c name="create_date" /> <c name="modify_date" /> <c name="is_ms_shipped" /> </t> </o> =================================================*/ select top 10 --需要显示的列,所对应的表别名,作为item --改变列的显示顺序会改变xml的层级 o.object_id, --作为o的item中的object_id属性 t.name, --属性t的item中的name属性 c.name --属性作为c的item中的name属性 from sys.objects o inner join sys.tables t on o.object_id = t.object_id inner join sys.columns c on t.object_id = c.object_id for xml auto, type /*=============================================== <t object_id="37575172" name="wcObjects"> <c name="name" /> <c name="object_id" /> <c name="principal_id" /> <c name="schema_id" /> <c name="parent_object_id" /> <c name="type" /> <c name="type_desc" /> <c name="create_date" /> <c name="modify_date" /> <c name="is_ms_shipped" /> </t> =================================================*/ select top 10 --需要显示的列,所对应的表别名,作为item --改变列的显示顺序会改变xml的层级 t.object_id, --作为t的item中的object_id属性 t.name, --属性t的item中的name属性,也就是说t有2个属性 c.name --属性作为c的item中的name属性 from sys.objects o inner join sys.tables t on o.object_id = t.object_id inner join sys.columns c on t.object_id = c.object_id for xml auto, type /*=============================================== <wc object_id="3" schema_id="4"> <wc_name>sysrscols</wc_name> </wc> <wc object_id="5" schema_id="4"> <wc_name>sysrowsets</wc_name> </wc> <wc object_id="7" schema_id="4"> <wc_name>sysallocunits</wc_name> </wc> =================================================*/ select top 3 1 as tag, null as parent, object_id as [wc!1!object_id], name as [wc!1!wc_name!element], schema_id as [wc!1!schema_id] from sys.objects o for xml explicit, type /*=============================================== <w> <wc wc_name="sysrscols" object_id="3"> <schema_id>4</schema_id> </wc> <wc wc_name="sysrowsets" object_id="5"> <schema_id>4</schema_id> </wc> <wc wc_name="sysallocunits" object_id="7"> <schema_id>4</schema_id> </wc> </w> =================================================*/ select top 3 name as '@wc_name', --属性 object_id as '@object_id', --属性 schema_id --item from sys.objects o for xml path('wc'), root('w'), type --2.把xml转化为关系型 declare @book xml set @book = CAST('<book> <chapters> <chapter id="1">Installation,Upgrades</chapter> </chapters> <chapters> <chapter id="2">Configuring SQLServer</chapter> </chapters> </book>' as XML ) --xml文档的句柄 declare @document int --取得xml文档的句柄 exec sp_xml_preparedocument @document output, @book select chapter_id, chapter_name from openxml(@document, '/book/chapters', 1) with (chapter_id int 'chapter/@id', chapter_name nvarchar(100) 'chapter') --删除文档句柄指定的xml文档的内部表示形式,并使该文档句柄无效 exec sp_xml_removedocument @document
2、分层
在SQL Server 2008中引入了hierarchyid数据类型,可以用来做本地存储,可以表示树层次结构中节点的位置,其中包含了几个可以操作、遍历层次结构的内置方法。
--1.建表,注意方法名称的大小写 create table dbo.webpage (webpageID hierarchyid not null, positionDESC as webpageid.GetLevel(), --取得层级 pageurl nvarchar(50) not null ) --插入数据 insert into dbo.webpage(webpageID,pageurl) values('/','http://wc.com') insert into dbo.webpage(webpageID,pageurl) values('/1/','http://wc.com/abc/') insert into dbo.webpage(webpageID,pageurl) values('/2/','http://wc.com/wc.htm') declare @parent hierarchyid set @parent = CONVERT(hierarchyid,'/1/') insert into dbo.webpage(webpageID,pageurl) values(@parent.GetDescendant(null,null), 'http://wc.com/abc/abc1.html') insert into dbo.webpage(webpageID,pageurl) values(@parent.GetDescendant(null,null), 'http://wc.com/abc/abc2.html') --2.显示层次数据 select webpageID, --二进制表示 webpageID.ToString(), --字符串表示 positionDESC, pageurl from dbo.webpage --3.返回指定层级的向上指定级数的层级 select CONVERT(hierarchyid,'/1/1/').GetAncestor(1).ToString(), hierarchyid::Parse('/1/1/'), --解析字符串转为hierarchyid hierarchyid::Parse('/1/1/').GetAncestor(1).ToString() --4返回指定层级的子节点 select CONVERT(hierarchyid,'/1/').GetDescendant(null,null).ToString() --5.返回节点的深度 sel ect CONVERT(hierarchyid,'/1/1/1/1/').GetLevel() --6.返回根节点 select hierarchyid::GetRoot() select * from dbo.webpage where webpageID = hierarchyid::GetRoot() --7.验证是否是当前节点的子节点 select hierarchyid::Parse('/1/').IsDescendantOf('/') --8.修改节点位置 select hierarchyid::Parse('/1/1/'), hierarchyid::Parse('/1/1/').GetReparentedValue('/1/', --原来的上一级节点 '/2/') --现在的上一级节点
3、空间数据
SQL Server 2008引入了原生的空间数据存储,提供了geography和geometry两种新的数据类型,这些数据类型为位置和制图应用程序、几何形状的表示,提供了内建的功能。
geography数据类型可以存储圆球空间,也可以存储坐标的经度、纬度、点、多边形、曲线、集合。
geometry数据类型表示欧几里得坐标空间数据,也可以存储点、多边形、曲线、集合。SQL Server 2008支持文本(WKT)、二进制(WKB)、地理标记语言(GML)的XML格式,来表示矢量几何映射对象。开放地理空间联盟(OGC)中常用这些格式,这里通过WKT格式使用geography数据类型。
--1.空间数据 with Geo as ( select id, lon, lat, geography::Parse('POINT('+lon+space(1)+lat+')') as g from ( select 1 as id,'-16.96732' as lon,'36.943' as lat union all select 1,'-16.58963','36.943' )a where lon is not null and lat is not null ) --2.计算坐标之间的距离 select s.ID, g.STDistance(geography::Parse('POINT('+r.LON+SPACE(1)+r.LAT+')')) from Geo s inner join ( select 1 as id,'-116.26598' as lon,'39.27763' as lat union all select 1,'-16.32683','36.94673' ) r on s.ID = r.ID --3.建立有空间数据的表 create table x ( v int not null identity(1,1) primary key, geog geography not null, geogWKT as geog.STAsText() ) --4.添加空间数据 insert into x(geog) values(geography::Parse('POLYGON( (-93.123 36.943, -93.126 36.953, -94.129 36.986, -93.123 36.943) )' ) ), --多边形,开始坐标和结束坐标必须相同,注意polygon中必须包含2层括号,否则报错 (geography::Parse('POINT(-93.123 36.943)')), --点坐标 (geography::Parse('LINESTRING(-93.123 36.943, -93.126 36.953)') ) --两坐标之间的线 --5.地理数据的计算 select v, geogWKT, geog.STDistance('POINT (-93.123 36.985)'), --距离 geog.STIntersects('POINT (-93.123 36.943)'), --是否有交集 geog.STLength(), --长度 geog.STArea(), --多边形面积 geog.STAsText() --WKT格式的坐标 from x