⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 11398.htm

📁 一本很基础的SQL讲解
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>使用 <B>sql:variable()</B>,可以在 XQuery 或 XML DML 表达式中应用 SQL 变量的值。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>通过 <B>sql:column()</B>,可以在 XQuery 或 XML DML 上下文中使用来自关系列的值。 </P></TD></TR></TBODY></TABLE>
<P>这种方法允许应用程序参数化查询,如下面的示例所示。<B>Sql:column()</B> 的用法与前者类似,并且还带来其他的好处。正如基于成本的查询优化器所确定的,可以使用列的索引来提高效率。此外,也可以使用计算列。 </P>
<P>XML 和用户定义的类型不允许与 <B>sql:variable()</B> 和 <B>sql:column()</B> 一起使用。</P>
<P>例:使用 sql:variable() 的跨域查询</P>
<P>在这种查询中,&lt;book&gt; 元素的 ISBN 是使用 SQL 变量 @isbn 来传入的。代替使用常量,sql:variable() 提供 ISBN 的值,并且该查询可以用于搜索任何 ISBN,而不只是 ISBN 为 0-7356-1588-2 的 元素。</P><PRE class=codeSample>DECLARE @isbn varchar(20)
SET     @isbn = '0-7356-1588-2'
SELECT  xCol
FROM    docs
WHERE   xCol.exist ('/book[@ISBN = sql:variable("@isbn")]') = 1
</PRE>
<H4>从 XML 数据生成行集</H4>
<P>在自定义属性管理和数据交换场景中,应用程序通常将 XML 数据的某些部分映射到行集。例如,为了将输入参数表传送到存储过程或函数,应用程序需要将数据转换成 XML,并且将其作为 XML 数据类型的参数传入。在存储过程或函数中,行集是从 XML 参数生成的。 </P>
<P>SQL Server 2000 为此提供了 <B>OpenXml()</B>。它简化了从 XML 实例生成行集的过程,方法是指定行集的关系架构以及将 XML 实例内的值映射到行集中的列的方式。 </P>
<P>另外,还可以使用 <B>nodes() </B>方法来生成 XML 实例中的节点上下文,并且在 <B>value()</B>、<B>query()</B>、<B>exist()</B> 和 <B>nodes()</B> 方法中使用该节点上下文来生成所期望的行集。<B>nodes()</B> 方法接受 XQuery 表达式,在 XML 列的每个 XML 实例中对其进行求值,并且有效地使用 XML 索引。下一个示例演示如何将 <B>nodes()</B> 方法用于行集生成。 </P>
<P>例:从 XML 实例提取属性</P>
<P>假定要提取名字不是“David”的作者的名和姓,将其作为由两列(FirstName 和 LastName)组成的一个行集。通过使用<B> nodes()</B> 和 <B>value()</B> 方法,您可以达到此目的,如下所示:</P><PRE class=codeSample>SELECT nref.value('first-name[1]', 'nvarchar(50)') FirstName,
       nref.value('last-name[1]', 'nvarchar(50)') LastName
FROM   docs CROSS APPLY xCol.nodes('//author') AS R(nref)
WHERE  nref.exist('.[first-name != "David"]') = 1
</PRE>
<P>在这个示例中,<B>nodes(</B>'//author'<B>)</B> 产生一个指向每个 XML 实例的 元素的引用的行集。作者的名和姓是通过对与这些引用有关的 <B>value()</B> 方法求值来获得的。要获得好的性能,需要建立 XML 列的索引,这是下一部分的主题。</P>
<H3>#p#建立 XML 数据的索引</H3>
<P>XML 数据是以内部二进制形式存储的,存储容量可以达到 2 GB。每个查询在运行时一次或多次地解析表中每一行的 XML BLOB。这会使查询处理的速度变得很慢。如果在工作负荷中常常需要进行查询,则建立 XML 列的索引是有好处的,不过,这样做必须考虑在修改数据的过程中维护 XML 索引的成本。</P>
<P>XML 索引是通过一个新的 DDL 语句在类型化和非类型化的 XML 列中创建的。这为该列中的所有 XML 实例创建了一个 B+ 树。XML 列中的第一个索引是“主 XML 索引”。通过这个索引,可以在 XML 列中支持三种类型的次 XML 索引来加速普通类的查询,如下一节所述。</P>
<H4>主 XML 索引</H4>
<P>在基表(即定义 XML 列的表)的主键中,主 XML 索引需要聚集索引。它在 XML 节点的信息集项的一个子集中创建一个 B+ 树。B+ 树的列表示标记,例如元素和属性名称、节点值和节点类型。其他的列捕获 XML 数据中的文档顺序和结构,以及从 XML 实例的根节点到每个节点的路径,从而有效地对路径表达式进行求值。基表的主键在主 XML 索引中复制,以使索引行与基表行相关。 </P>
<P>XML 架构中给定的标记和类型名称被映射为整数值,而映射值存储在 B+ 树中以优化存储。索引中的路径列按照相反的顺序(即从节点到 XML 实例的根)存储映射值的串联。当路径后缀已知时(在一个路径表达式中,如 //author/last-name),相反的表示使得可以匹配路径值。 </P>
<P>如果对基表进行分区,则需要以相同的方式对主 XML 索引进行分区,也就是使用相同的分区函数和分区架构。</P>
<P>全部的 XML 实例都是从 XML 列检索的(SELECT * FROM docs 或 SELECT xCol FROM docs)。需要 XML 数据类型方法的查询使用主 XML 索引,从索引本身返回标量值或 XML 子树。</P>
<P>例:创建主 XML 索引</P>
<P>下面的语句在表 docs 的 XML 列 xCol 中创建一个名为 idx_xCol 的 XML 索引。</P><PRE class=codeSample>CREATE PRIMARY XML INDEX idx_xCol on docs (xCol)
</PRE>
<H4>次 XML 索引</H4>
<P>一旦主 XML 索引创建完毕,就可以创建次 XML 索引来加速工作负荷中不同类的查询。三种类型的次 XML 索引 — PATH、PROPERTY 和 VALUE — 分别对基于路径的查询、自定义属性管理方案和基于值的查询有利。 </P>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>PATH 索引在主 XML 索引的列 (path, value) 中构建 B+ 树。该路径的值是通过计算路径表达式和节点的值得出的,如果提供了一个路径值,则也可以使用所提供的值。在已知 PATH 索引开始字段的情况下,查找 PATH 索引可以加速路径表达式的求值。最常见的情况是在 SELECT 语句的 WHERE 子句中对 XML 列使用 <B>exist()</B> 方法。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>PROPERTY 索引在主 XML 索引的列 (PK, path, value) 中创建 B+ 树,其中 PK 是基表的主键。此索引对 XML 实例中的属性值查找有利。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>最后,VALUE 索引在主 XML 索引的列 (value, path) 中创建一个 B+ 树。此索引对节点的值已知但是其路径没有准确地在查询中指定的查询有利。这通常出现在祖先或自身 (descendant-or-self) 轴查询中,例如,//author[last-name="Howard"],其中, 元素可以出现在层次的任何一层。它还可以出现在“wildcard”查询中,例如 /book [@* = "novel"],其中,查询查找具有“novel”属性值的 元素。此外,VALUE 索引还可用于对类型化的 XML 进行基于值的范围扫描。 </P></TD></TR></TBODY></TABLE>
<P>可以容纳多达 128 层的 XML 层次;在插入和修改的过程中,如果 XML 实例包含更长的路径,则会被拒绝。 </P>
<P>类似地,可以建立一个节点值的前 128 个字节的索引;系统中可以容纳更长的值,但是不会建立索引。</P>
<P>例:基于路径的查找</P>
<P>假定下面的查询在工作负荷中是常见的:</P><PRE class=codeSample>SELECT xCol
FROM   docs
WHERE  xCol.exist ('/book[@genre = "novel"]') = 1
</PRE>
<P>路径表达式 /book/@genre 和值“novel”对应于 PATH 索引的键字段。因此,类型 PATH 的次 XML 索引有助于此工作负荷:</P><PRE class=codeSample>CREATE XML INDEX idx_xCol_Path on docs (xCol)
   USING XML INDEX idx_xCol FOR PATH
</PRE>
<P>例:获取对象的属性</P>
<P>考虑下面的查询,它从表 T 的每一行检索书的“genre”、“title”和 ISBN 属性:</P><PRE class=codeSample>SELECT xCol.value ('(/book/@genre)[1]', 'varchar(50)'),
    xCol.value ('(/book/title)[1]', 'varchar(50)'),
    xCol.value ('(/book/@ISBN)[1]', 'varchar(50)')
FROM    docs
</PRE>
<P>属性索引可用于这种情况,该索引创建如下:</P><PRE class=codeSample>CREATE XML INDEX idx_xCol_Property on docs (xCol)
   USING XML INDEX idx_xCol FOR PROPERTY
</PRE>
<P>例:基于值的查询</P>
<P>在下面的查询中,祖先或自己轴 (//) 指定了部分路径,这样,基于 ISBN 值的查询就可以从 VALUE 索引的使用中受益:</P><PRE class=codeSample>SELECT xCol
FROM    docs
WHERE    xCol.exist ('//book[@ISBN = "1-8610-0157-6"]') = 1
</PRE>
<P>VALUE 索引创建如下:</P><PRE class=codeSample>CREATE XML INDEX idx_xCol_Value on docs (xCol)
   USING XML INDEX idx_xCol FOR VALUE
</PRE>
<H4>内容索引</H4>
<P>可以在 XML 列中创建全文本索引;这会建立 XML 值内容的索引而忽略 XML 标记。属性值不是全文本索引的(因为它们被认为是标记的一部分),而元素标记被用作标记边界。可以在 XML 列中创建 XML 和全文本索引,并且组合使用全文本搜索和 XML 索引。使用全文本索引作为第一个筛选器来缩小选择范围,接着再应用 XQuery 进一步筛选。</P>
<P>使用 <B>CONTAINS() </B>和 XQuery <B>contains() </B>的全文本搜索有不同的语义。后者是子字符串匹配,而前者是使用词根检索的标记匹配。 </P>
<P>例:在 XML 列中创建全文本索引</P>
<P>在 XML 列中创建全文本索引的步骤与在其他 SQL 类型列中创建全文本索引的步骤是非常相似的。需要在基表中有一个唯一的键列。DDL 语句如下,其中,PK__docs__7F60ED59 是该表的单列主键索引:</P><PRE class=codeSample>CREATE FULLTEXT CATALOG ft AS DEFAULT
CREATE FULLTEXT INDEX ON dbo.docs (xCol) KEY INDEX PK__docs__7F60ED59
</PRE>
<P>例:组合全文搜索和 XML 查询</P>
<P>下面的查询检查 XML 值是否在书的标题中包含单词“Secure”:</P><PRE class=codeSample>SELECT * 
FROM   docs 
WHERE  CONTAINS(xCol,'Secure') 
AND    xCol.exist('/book/title/text()[contains(.,"Secure")]') =1
</PRE>
<P><B>CONTAINS()</B> 方法使用全文本索引来产生一个 XML 值的子集,它包含文档中所有的单词“Secure”。<B>exist()</B> 子句确保单词“Secure”出现在书的标题中。</P>
<H4>#p#使用 XML 索引执行查询</H4>
<P>XML 索引可以加速查询的执行。查询总是针对 XML 列中的主 XML 索引进行编译(如果存在的话)。为整个查询(包括关系部分和 XML 部分)制订一个查询计划,该计划可以通过数据库引擎基于成本的优化器进行优化。根据查询优化器的成本估算来选择次 XML 索引。 </P>
<H4>XML 索引的目录视图</H4>
<P>目录视图用于提供关于 XML 索引的元数据信息。目录视图 <B>sys.indexes</B> 包含带有索引“type”3 的 XML 索引项。“name”列包含 XML 索引的名称。 </P>
<P>XML 索引也记录在目录视图 <B>sys.xml_indexes</B> 中,它包含所有的 <B>sys.indexes</B> 列以及一些对 XML 索引有意义的特别的列。列“secondary_type”中的值 NULL 表示主 XML 索引,值“P”、“R”和“V”分别代表 PATH、PROPERTY 和 VALUE 次 XML 索引。 </P>
<P>可以从表值函数 sys.fn_indexinfo() 中找到 XML 索引的空间使用。它提供的信息包括所占用的磁盘页数、按字节计算的平均行大小、记录数,以及其他包括 XML 索引在内的所有索引类型的信息。这些信息可用于每个数据库分区;XML 索引使用与基表相同的分区架构和分区函数。 </P>
<P>例:XML 索引的空间使用</P><PRE class=codeSample>SELECT sum(Pages)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -