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

📄 11398.htm

📁 一本很基础的SQL讲解
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P>例:存储使用带有 TYPE 指令的 FOR XML 生成的 XML 数据</P>
<P>通过 TYPE 指令增强的 FOR XML 可以生成像 XML 数据类型实例这样的结果。结果 XML 可以分配到 XML 列、变量或参数。在下面的语句中,使用 FOR XML TYPE 生成的 XML 实例被分配给 XML 数据类型的变量 @xVar。可以使用 XML 数据类型的方法来查询变量。</P><PRE class=codeSample>DECLARE @xVar XML
SET     @xVar = (SELECT * FROM docs FOR XML AUTO,TYPE)
</PRE>
<H4>#p#存储表示</H4>
<P>XML 数据类型的实例存储在内部的二进制表示中,该表示是可流化的,并且经过了优化,从而可以更有效地进行解析。标记映射到整型值,而映射的值存储在内部表示中。这也产生了一些数据的压缩。 </P>
<P>对于非类型化的 XML,节点值存储为 Unicode (UTF-16) 字符串,因此需要进行运行时类型转换才能执行操作。例如,为了求谓词 /book/price &gt; 9.99 的值,必须将该书的价格值转换为小数。而对于类型化的 XML,值的编码类型为在 XML 架构中指定的类型。这使得数据的解析更加有效,并且还不必进行运行时转换。 </P>
<P>存储的二进制形式被限制为每 XML 实例 2 GB,这可以适应大部分的 XML 数据。此外,XML 层次的深度还被限制为 128 层。 </P>
<P>XML 数据的信息集内容被保留。但是,它不可能是与文本 XML 一模一样的副本,因为下列信息没有保留:无关紧要的空白、属性的顺序、命名空间前缀和 XML 声明。</P>
<H4>数据建模考虑事项</H4>
<P>通常,关系数据类型和 XML 数据类型的列的组合比较适合数据建模。可以将 XML 数据中的一些值存储在关系列中,而将其余的值或全部的 XML 值存储在 XML 列中。这可以产生更好的性能和锁定特性。 </P>
<P>对于 singleton 值(即单值属性),XML 数据中的值可以提升为同一个表中的计算列。多值属性需要单独的属性表,该表必须使用触发器进行填充和维护。查询需要直接针对属性表进行编写。</P>
<P>对于锁定和更新特性,存储在 XML 列中的 XML 数据的粒度是至关重要的。SQL Server 将相同的锁定机制用于 XML 和非 XML 数据。如果粒度比较大,则在多用户的情况下,为了更新而锁定大的 XML 实例会引起吞吐量的下降。而另一方面,严格的分解会失去对象的封装性并增加重新组合的成本。</P>
<H3>查询和修改 XML 数据</H3>
<P>查询存储在 XML 列中的 XML 实例需要解析列中的二进制 XML 数据。与解析文本形式的 XML 数据相比,解析二进制的 XML 要快得多。XML 索引避免了重新解析,这将在“建立 XML 数据的索引”一节中进行讨论。</P>
<H4>XML 数据类型中的方法</H4>
<P>如果感兴趣,可以检索全部 XML 值,也可以检索部分 XML 实例。这可以使用四个 XML 数据类型的方法来实现:<B>query()</B>、<B>value()</B>、<B>exist()</B> 和 <B>nodes()</B>,它们接受 XQuery 表达式作为参数。第五个方法 <B>modify()</B> 允许修改 XML 数据并接受 XML 数据修改语句作为输入。</P>
<P><B>query()</B> 方法用于提取 XML 实例的部分。XQuery 表达式求值为一个 XML 节点列表。以这些节点中的每一个为根的子树按照文档顺序返回。结果类型为非类型化的 XML。 </P>
<P><B>value() </B>方法从 XML 实例提取标量值。它返回 XQuery 表达式所求值的节点的值。该值被转换为 <B>value()</B> 方法的第二个参数所指定的 T-SQL 类型。</P>
<P><B>exist() </B>方法用于对 XML 实例进行存在性检查。如果 XQuery 表达式求值为非空节点列表,则返回 1;否则,返回 0。 </P>
<P><B>nodes()</B> 方法产生特定 XML 数据类型的实例,每个实例都将其上下文设置为 XQuery 表达式所求值的不同节点。特定的 XML 数据类型支持 <B>query()</B>、<B>value()</B>、 <B>nodes()</B> 和 <B>exist()</B> 方法,并且可以用于 <B>count(*)</B> 聚合和 NULL 检查。所有其他的使用都会产生错误。</P>
<P><B>modify()</B> 方法允许修改 XML 实例的某些部分,例如添加或删除子树,或者更新标量值(如将书的价格从 9.99 替换为 39.99)。</P>
<P>例:使用 query() 方法</P>
<P>考虑下面的表 docs 的 XML 列 xCol 中的查询,它提取 元素下的任何位置的 id 为 123 的 元素。该查询也从整型主键列检索值。SELECT 列表中的 <B>query()</B> 方法会为生成 元素序列的表中的每一行进行求值, 元素及其子树是按照文档顺序进行检索的。对于每个 XML 实例,如果没有 id 为 123 的 元素或者其下没有 元素,则不会返回结果,也就是说,<B>query()</B> 方法的返回值为 NULL。 </P><PRE class=codeSample>SELECT pk, xCol.query('/doc[@id = 123]//section')   
FROM   docs
</PRE>
<P>NULL 返回值可以在外部 SELECT 语句中过滤掉。或者也可以使用 <B>exist()</B> 方法,如下一个示例所示。</P>
<P>例:使用 exist() 方法</P>
<P>考虑下面的查询,它在表 docs 的 XML 列 xCol 中包括 <B>query()</B> 和 <B>exist()</B> 方法。<B>exist()</B> 方法求路径表达式 /doc[@id = 123] 的值,检查是否存在顶层 元素,该元素具有一个称为 id 的属性,且其值为 123。对于每个这样的行,SELECT 子句中的 <B>query() </B>方法都会进行求值;在这个示例中,<B>query()</B> 方法在 元素下的任何位置都产生一个 元素序列。从<B> exist()</B> 方法返回 0 的任何行都会被忽略。</P><PRE class=codeSample>SELECT xCol.query('/doc[@id = 123]//section')   
FROM   docs
WHERE  xCol.exist ('/doc[@id = 123]') = 1
</PRE>
<P>例:使用 value() 方法</P>
<P>下面的查询使用 <B>value()</B> 方法以 Unicode 字符串的形式提取文档第三部分的标题。结果的 SQL 类型的 nvarchar(max) 被指定为 <B>value()</B> 方法的第二个参数。XQuery 函数 <B>data()</B> 从 节点提取标量值。</P>
<P>SELECT xCol.value( 'data((/doc//section[@num = 3]/heading)[1])', 'nvarchar(max)') FROM docs</P>
<H4>XQuery 语言</H4>
<P>众多的 XML 都来源于存储在文件系统、Web 服务或配置文件中的 Office 文档。事实上,以 XML 格式或作为虚拟 XML 文档生成的数据正在不断地增加。为了处理这些数量越来越多的数据,一种强大的查询语言 XQuery 应运而生。在 XQuery 语言规范(位于 <A href="http://www.w3.org/TR/xquery" target=_blank>http://www.w3.org/TR/xquery</A>)中将选择 XQuery 的理由描述为: </P>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>一种巧妙地使用 XML 结构的查询语言,可以跨各种数据表示查询,而不管这些数据是物理存储在 XML 中,还是通过中间件被视为 XML。该规范描述了一种称为 XQuery 的查询语言,它旨在能广泛应用于许多类型的 XML 数据源。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>XQuery 旨在满足 W3C XML 查询工作组 XML 查询 1.0 要求和 XML 查询用例中的用例所确定的要求。它是一种旨在使查询简洁易懂的语言。它还相当地灵活,可以查询大范围的 XML 信息源,其中包括数据库和文档。 </P></TD></TR>
<TR>
<TD class=listBullet vAlign=top>&#8226;</TD>
<TD class=listItem>
<P>XQuery 还可以概括为如下表述:XQuery 语言之于 XML 正如 SQL 语言之于关系数据库。</P></TD></TR></TBODY></TABLE>
<P>内嵌于 T-SQL 的 Xquery 子集(位于 <A href="http://www.w3.org/TR/xquery/" target=_blank>http://www.w3.org/TR/xquery/</A>)是一种支持查询 XML 数据类型的语言。这种语言正在由 Worldwide Web Consortium (W3C) 进行开发(目前处于最后请求状态),所有主要的数据库厂商(包括 Microsoft 在内)都参与其中。我们的实现与 2003 年 11 月发布的 XQuery 草案是一致的。</P>
<P>XQuery 将 XPath 2.0 作为导航语言包括在内。SQL Server 2005 的 XQuery 实现提供了用于遍历节点 (for)、节点检查 (where)、返回值 (return) 和排序 (order by) 的构造。它也提供了用于在查询过程中重新进行数据构形的元素构造。</P>
<P>SQL Server 2005 还提供了用于 XML 数据类型的数据修改 (DML) 的语言构造(请参阅下面的“数据修改”一节以获得更多信息)。下面的示例演示了如何将 XQuery 用于 XML 数据类型。</P>
<P>例:使用 XQuery 中丰富的语言构造</P>
<P>下面的查询显示了如何一起使用几个 XQuery 语言构造。它从 id 为 123 的文档返回区域号为 3 和更高的区域中的标题,并将其包装在新标记 中。 </P><PRE class=codeSample>SELECT pk, xCol.query('
   for $s in /doc[@id = 123]//section
   where $s/@num &gt;= 3
   return &lt;topic&gt;{data($s/heading)}&lt;/topic&gt;')   
FROM docs
</PRE>
<P>“for”遍历 id 为 123 的&lt;doc&gt; 元素下的所有&lt;section&gt; 元素,并且将每个这样的&lt;section&gt; 元素绑定到变量 $s。“where”确保区域号(&lt;section&gt; 元素的 @num 属性)为 3 或更高。该查询按照文档顺序返回区域&lt;heading&gt; 中的值,并且将其包装在一个称为&lt;topic&gt; 的构造元素中。</P>
<H4>查询编译和执行</H4>
<P>SQL 语句是由 SQL 解析器解析的。当它遇到 XQuery 表达式时,它就会跳转到 XQuery 编译器,然后编译 XQuery 表达式。这会产生一个查询树,并将其嫁接到整个查询的查询树上。 </P>
<P>整个查询树会进行查询优化并产生物理查询计划,该计划是根据基于成本的评估得出的。Showplan 输出显示了大部分关系运算符和一些新的运算符(例如,用于 XML 处理的 UDX)。 </P>
<P>查询执行与关系框架中的其余部分一样,都是面向元组的。在表 docs 的每一行上都求 WHERE 子句的值;这需要在运行时解析 XML BLOB 以求出 XML 数据类型方法的值。如果条件满足,则锁定行,然后在行中求 SELECT 子句的值。结果以 XML 数据类型的形式产生(用于 <B>query()</B> 方法),并且转换成指定的目标类型(用于 <B>value()</B> 方法)。 </P>
<P>而如果该行不满足 WHERE 子句中的条件,它就会被忽略,执行转到下一行。</P>
<H4>#p#XML 数据修改</H4>
<P>SQL Server 2005 提供了用于数据修改的构造作为对 XQuery 的一个扩展。子树可以在指定的节点之前或之后插入,或者作为最左边或最右边的子节点插入。此外,子树也可以插入到父节点,在这种情况下,它成为父节点最右边的子节点。属性、元素和文本节点插入都支持。</P>
<P>支持删除子树。在这种情况下,整个子树就从 XML 实例中被移除。 </P>
<P>标量值可以用新的标量值进行替换。 </P>
<P>例:将子树插入 XML 实例</P>
<P>这个示例显示了 <B>modify()</B> 方法的使用,它将一个新的&lt;section&gt; 元素插入编号为 1 的 元素的右边。</P><PRE class=codeSample>UPDATE docs SET xCol.modify('
  insert 
   &lt;section num="2"&gt;
         &lt;heading&gt;Background&lt;/heading&gt;
&lt;/section&gt;                
  after (/doc/section[@num=1])[1]')
</PRE>
<P>例:将这本书的价格更新为 $49.99</P>
<P>下面的更新语句将 ISBN 为 1-8610-0311-0 的书的&lt;price&gt; 替换为 $49.99。该 XML 实例是通过 XML 架构 http://myBooksinstance 进行类型化的,因而就有了 XML 数据修改语句中的命名空间声明。</P><PRE class=codeSample>UPDATE XmlCatalog
SET    Document.modify ('
    default namespace = "http://myBooks"
    replace value of (/bookstore/book[@ISBN=
"1-8610-0311-0"]/price)[1] with 49.99')
</PRE>
<H4>类型检查和静态错误</H4>
<P>XQuery 引入了类型检查。编译阶段检查 XQuery 表达式和数据修改语句的静态类型正确性,并且将 XML 架构用于类型推理(在类型化 XML 的情况下)。如果表达式在运行时由于类型安全冲突而失败,则会产生静态类型错误。静态错误的例子有:将一个字符串与一个整数相加、在操作需要单值的地方接收一个值序列,以及查询不存在的节点来查找类型化数据。对于因类型不匹配而导致的静态错误,显式转换到正确的类型是一种变通方法。XQuery 运行时错误被转换成空序列。 </P>
<P>如果编译器不能确定在运行时是否保证有 singleton 元素,则需要 singleton 元素的定位步骤、函数参数和运算符(例如,eq)就会返回错误。这种问题常常因非类型化的数据而产生。例如,查找属性需要 singleton 父元素;顺序选择单个的父节点就足够了。 </P>
<P>例:value() 方法中的类型检查</P>
<P>下面的查询是在非类型化的 XML 列中进行的,它需要 //author/last-name 中的顺序规范,因为 <B>value()</B> 方法需要 singleton 节点作为第一个参数。如果没有,则编译器就不能确定在运行时是否只出现一个&lt;last-name&gt; 节点。</P><PRE class=codeSample>SELECT xCol.value('(//author/last-name)[1]', 'nvarchar(50)') LastName
FROM   docs
</PRE>
<P>通过求 <B>node()-value()</B> 组合的值来提取属性值可以不需要顺序规范,如下一个示例所示。</P>
<P>例:已知的 singleton 元素</P>
<P>如下所示的 <B>nodes()</B> 方法为每个&lt;book&gt; 元素生成单独的行。对&lt;book&gt; 节点求值的 <B>value()</B> 方法提取 @genre 的值,@genre 作为一个属性,是 singleton 元素。 </P><PRE class=codeSample>SELECT nref.value('@genre', 'varchar(max)') LastName
FROM   docs CROSS APPLY xCol.nodes('//book') AS R(nref)
</PRE>
<H4>跨域查询</H4>
<P>如果数据驻留在关系数据类型的列和 XML 数据类型的列的组合中,就可能需要编写查询来组合关系数据处理和 XML 数据处理。通过使用带有 TYPE 指令的 <B>FOR XML</B>,可以将关系列和 XML 列中的数据转换成 XML 数据类型的实例,并使用 XQuery 对其进行查询。相反地,可以从 XML 值生成行集,并且使用 T-SQL 来对其进行查询,如下面的“从 XML 数据生成行集”一节所示。</P>
<P>编写跨域查询的一个更加方便和有效的方法是,使用 SQL 变量的值,或者使用 XQuery 或 XML 数据修改表达式中的列: </P>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>

⌨️ 快捷键说明

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