找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4171|回复: 0

XQuery, 连通SQL与NOSQL的桥梁 |走在溪边

[复制链接]
发表于 2011-12-8 14:08:51 | 显示全部楼层 |阅读模式
在企业应用软件设计中,原来往往只需要与一个SQL数据打交道,现在却往往要连接多个数据源,这些数据源可能是SQL数据库、NOSQL数据、XML文件、网站数据等。这么多复杂的数据,有没有办法让它们构成一个数据中心,以相对统一的方式进行管理和数据处理呢?XQuery是合适的前端。
具体做法:
1、在企业服务器上设定数据库连接池,并指定连接名称。
2、选择合适的xquery引擎,并绑定企业服务器。
3、扩展xquery的函数用于操作数据库,比如连接关系数据库,扩展以下函数,原型如下:
declare function sql:select($a as xs:string, $b as xs:string) as node() external;
declare function sql:update($a as xs:string, $b as xs:string) as xs:boolean external;

4、使用xquery查询各单元的数据,合并处理后返回结果。
5、使用xquery维护各数据单元。


这样做有以下的优缺点:
优点:
1、与Sql一样,对外提供统一查询和维护方式。
2、可以以一种统一的方式构建数据中心管理工具。
3、按数据特性,选择合适高效的存储单元。

以后的模式是否应该这样:
    一些厂商提供各种具有一定特性的(比如Sql、Cache、Xml、Json、 File)的高性能数据单元。
    一些厂商提供高性能的数据中心管理工具,主要的查询和维护语言是xquery,也可延伸sql。
     数据库厂商不需要面面俱到,只需要提供的存储单元足够高效就可以。
4、提高SQL数据库的分布性
5、提高内容的分布性。
6、更有效规划内容的存储方式。
     
缺点:
     1、xquery的性能还需要提高。
     2、增加了数据存储规划复杂性。

下面是具体使用的例子:
1、查询某类别下产品货号,类别以xml的方式保存在dbxml库,货号放在Sql Server中。
  1. declare function sql:select($a as xs:string, $b
  2. as xs:string) as xs:string external;
  3. declare function sql:update($a as
  4. xs:string, $b as xs:string) as xs:boolean external;
  5. let $sTxt :=
  6. xqilla:parse-xml($str)
  7. let $ID := $sTxt/search/@ID
  8. let $t :=
  9. doc("dbxml:/product/productcategory.dbxml/data")//Category[@ID=$ID]
  10. let $k :=
  11. data($t/@ID|$t//Category/@ID)
  12. let $s :=
  13. concat("'",string-join($k,"','"),"'")
  14. let $sql := <Sql>
  15.         
  16.     select  rtrim(ItemNo) as Code,Name,Spec  from ItemDetail  where CategoryID
  17. in ({$s})
  18.                 order by ItemNo
  19.             FOR XML PATH
  20. ('Product'),ROOT ('Products')
  21.         </Sql>
  22. let $link :=
  23. "link_erp1"
  24. return  
  25. sql:select($link,$sql/text())
  26. 2、使用xquery查询企业资源。
  27. declare namespace fx = "http://local";
  28. declare function sql:select($a
  29. as xs:string, $b as xs:string) as node() external;
  30. declare function
  31. sql:update($a as xs:string, $b as xs:string) as xs:boolean
  32. external;
  33. declare function fx:trim( $arg as xs:string? )  as
  34. xs:string
  35. {
  36.     replace(replace($arg,'\s+
  37. [img=1,1]http://www.cnblogs.com/qianxj/aggbug/2168502.html?type=1[/img]
  38. [url=http://www.cnblogs.com/qianxj/archive/2011/12/08/2168502.html]本文链接[/url],''),'^\s+','')
  39. }
  40. ;
  41. (:let $ResourceType :="Supplier":)
  42. (:let $ResourceType
  43. :="Customer":)
  44. (:let $ResourceType :="Goods":)
  45. let $PageSize := 50
  46. let $PageIndex := 1
  47. let $link := "link_erp1"
  48. return
  49. (
  50.    
  51. if($ResourceType="Supplier") then
  52.     (
  53.         let $query :=
  54. <sql>
  55.             DECLARE @PageSize int
  56.             DECLARE
  57. @PageIndex int
  58.             set @PageSize = {$PageSize};
  59.             
  60. set @PageIndex = {$PageIndex};
  61.             WITH Temp AS
  62.             
  63. (
  64.               SELECT ROW_NUMBER() OVER(ORDER BY SupplierNo ASC) AS
  65. RowNumber,*
  66.               FROM Supplier1
  67.             )
  68.             
  69. SELECT  rtrim(SupplierID) as "@guid",
  70.                      rtrim(SupplierNo)
  71. as SupplierNo,
  72.                      rtrim(SupplierShort) as ShortName,
  73.    
  74.                  rtrim(SupplierName) as Name,
  75.                      
  76. rtrim(SupplierAddress) as Address,
  77.                      rtrim(CountryNo) as
  78. Country,
  79.                      rtrim(ProvinceNo) as Province
  80.             
  81.       FROM Temp
  82.             WHERE (RowNumber BETWEEN @PageSize*(@PageIndex-1)
  83. + 1 AND @PageSize * @PageIndex )
  84.             FOR XML PATH ('Supplier'),ROOT
  85. ('Suppliers')
  86.         </sql>
  87.         return
  88. sql:select($link,$query/text())
  89.     )
  90.     else
  91. if($ResourceType="Customer") then
  92.     (
  93.         let $query :=
  94. <sql>
  95.             DECLARE @PageSize int
  96.             DECLARE
  97. @PageIndex int
  98.             set @PageSize = {$PageSize};
  99.             
  100. set @PageIndex = {$PageIndex};
  101.             WITH Temp AS
  102.             
  103. (
  104.               SELECT ROW_NUMBER() OVER(ORDER BY CustomerNo ASC) AS
  105. RowNumber,*
  106.               FROM Customer
  107.             )
  108.             
  109. SELECT     rtrim(CustomerID) as "@guid",
  110.                     
  111. rtrim(CustomerNo) as CustomerNo,
  112.                     rtrim(CustomerShort) as
  113. ShortName,
  114.                     rtrim(CustomerName) as Name,
  115.             
  116.         rtrim(CustomerAddress) as Address,
  117.                     rtrim(Country)
  118. as Country
  119.             FROM Temp
  120.             WHERE (RowNumber BETWEEN
  121. @PageSize*(@PageIndex-1) + 1 AND @PageSize * @PageIndex )
  122.             FOR
  123. XML PATH ('Customer'),ROOT ('Customers')
  124.         </sql>
  125.         
  126. return sql:select($link,$query/text())
  127.     )else
  128.     ()
  129. )
复制代码


本文链接
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-26 04:08 , Processed in 0.019951 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表