顯示具有 DB2 - XML 標籤的文章。 顯示所有文章
顯示具有 DB2 - XML 標籤的文章。 顯示所有文章

2010年1月19日 星期二

PureXML using DB2 Express-C 9.7


/*
  1.測試 DB2 Express-C 9.7 pureXML
  2.兩個 xml 資料之間的 join
  3.一個 xml document 裡有多筆資料時的資料呈現
  p.s 程式中<>及縮排的空白為全形,使用前須先轉為single-byte
*/

-- 建立地區xsd,有地區代碼與地區英文名稱

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="region">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="regno" type="xs:string"/>
   <xs:element name="regename" type="xs:string"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
</xs:schema>

-- 註冊地區xsd

register xmlschema 'http://localhost/region/region.xsd' from c:\region.xsd as xsd_region complete
DB20000I REGISTER XMLSCHEMA 指令已順利完成。

-- p.s 從register中移除xsd的語法如下

drop xsrobject xsd_region


-- 由xsrobjects看註冊資料是否完整
select substr(targetnamespace,1,30),substr(schemalocation,1,30)
from syscat.xsrobjects where objectname = 'XSD_REGION'

1                 2
------------------------------ ------------------------------
http://localhost/region     http://localhost/region/region

  已選取 1 個記錄。

-- 建立地區table, regioninfo為xml格式

create table region
(
 id integer,
 regioninfo xml
)
DB20000I SQL 指令已順利完成。

-- 將地區xml資料寫成.sql檔,名稱為region.sql.格式必須符合xsd的定義

insert into region values
(1,xmlvalidate(xmlparse(document '<region>
                   <regno>1</regno>
                   <regename>Northern</regename>
                   </region>'
            ) according to xmlschema ID XSD_REGION));

insert into region values
(2,xmlvalidate(xmlparse(document '<region>
                   <regno>2</regno>
                   <regename>Central</regename>
                   </region>'
            ) according to xmlschema ID XSD_REGION));

insert into region values
(3,xmlvalidate(xmlparse(document '<region>
                   <regno>3</regno>
                   <regename>Eastern</regename>
                   </region>'
            ) according to xmlschema ID XSD_REGION));

insert into region values
(4,xmlvalidate(xmlparse(document '<region>
                   <regno>4</regno>
                   <regename>Western</regename>
                   </region>'
            ) according to xmlschema ID XSD_REGION));

insert into region values
(5,xmlvalidate(xmlparse(document '<region>
                   <regno>5</regno>
                   <regename>Southern</regename>
                   </region>'
            ) according to xmlschema ID XSD_REGION));


-- 執行region.sql將資料新增進table region

C:\>db2 -tf region.sql
DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

-- 使用xml function查看結果,並以table方式呈現

select regno,regename
from  region,
    xmltable('for $reg in $d/region return $reg'
         passing region.regioninfo as "d"
         COLUMNS regno varchar(5) path 'regno/text()',
             regename varchar(20) path 'regename/text()') t

REGNO REGENAME
----- --------------------
1   Northern
2   Central
3   Eastern
4   Western
5   Southern

  已選取 5 個記錄。

-- 建立銷售記錄xsd,有地區代碼、銷售日期、產品名稱、價格與數量

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="sales">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="regno" type="xs:string"/>
   <xs:element name="dt" type="xs:integer"/>
   <xs:element name="product" type="xs:string"/>
   <xs:element name="prize" type="xs:decimal"/>
   <xs:element name="quantity" type="xs:integer"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
</xs:schema>


-- 註冊銷售記錄xsd

register xmlschema 'http://localhost/sales/sales.xsd' from c:\sales.xsd as xsd_sales complete
DB20000I REGISTER XMLSCHEMA 指令已順利完成。

-- 建立銷售記錄table, salesrpt為xml格式

create table sales
(
  sno integer,
  salesrpt xml
)
DB20000I SQL 指令已順利完成。

-- 將銷售記錄xml資料寫成.sql檔,名稱為sales.sql

insert into sales values
(1,xmlvalidate(xmlparse(document '<sales>
                   <regno>1</regno>
                   <dt>20091011</dt>
                   <product>ring99</product>
                   <prize>12.55</prize>
                   <quantity>10</quantity>
                   </sales>'
            ) according to xmlschema ID XSD_SALES));

insert into sales values
(2,xmlvalidate(xmlparse(document '<sales>
                   <regno>3</regno>
                   <dt>20091011</dt>
                   <product>bangles</product>
                   <prize>1000</prize>
                   <quantity>1</quantity>
                   </sales>'
            ) according to xmlschema ID XSD_SALES));

insert into sales values
(3,xmlvalidate(xmlparse(document '<sales>
                   <regno>2</regno>
                   <dt>20091015</dt>
                   <product>ring33</product>
                   <prize>50</prize>
                   <quantity>6</quantity>
                   </sales>'
            ) according to xmlschema ID XSD_SALES));

insert into sales values
(4,xmlvalidate(xmlparse(document '<sales>
                   <regno>1</regno>
                   <dt>20091105</dt>
                   <product>ring99</product>
                   <prize>13</prize>
                   <quantity>10</quantity>
                   </sales>'
            ) according to xmlschema ID XSD_SALES));

insert into sales values
(5,xmlvalidate(xmlparse(document '<sales>
                   <regno>1</regno>
                   <dt>20091109</dt>
                   <product>ring99</product>
                   <prize>13.52</prize>
                   <quantity>10</quantity>
                   </sales>'
            ) according to xmlschema ID XSD_SALES));

insert into sales values
(6,xmlvalidate(xmlparse(document '<sales>
                   <regno>3</regno>
                   <dt>20091110</dt>
                   <product>ring99</product>
                   <prize>13.5</prize>
                   <quantity>5</quantity>
                   </sales>'
            ) according to xmlschema ID XSD_SALES));


-- 執行sales.sql將資料新增進table sales

C:\>db2 -tf sales.sql
DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

DB20000I SQL 指令已順利完成。

-- 使用xml function查看結果,並以table方式呈現

select regno,dt,product,prize,quantity
from  sales,
    xmltable('for $sal in $d/sales return $sal'
    passing sales.salesrpt as "d"
    COLUMNS regno varchar(5) path 'regno/text()',
    dt integer path 'dt/text()',
    product varchar(10) path 'product/text()',
    prize decimal(10,2) path 'prize/text()',
    quantity integer path 'quantity/text()') t2

REGNO DT     PRODUCT    PRIZE    QUANTITY
----- ----------- ---------- ------------ -----------
1    20091011 ring99      12.55       10
3    20091011 bangles     1000.00        1
2    20091015 ring33      50.00        6
1    20091105 ring99      13.00       10
1    20091109 ring99      13.52       10
3    20091110 ring99      13.50        5

  已選取 6 個記錄。


-- 地區xml資料與銷售記錄xml資料相互join,混用sql語法

select t3.regno,regename,dt,product,prize,quantity
from
(select regno,regename
from  region,
    xmltable('for $reg in $d/region return $reg'
         passing region.regioninfo as "d"
         COLUMNS regno varchar(5) path 'regno/text()',
             regename varchar(20) path 'regename/text()') t) t1,
(select regno,dt,product,prize,quantity
from  sales,
    xmltable('for $sal in $d/sales return $sal'
         passing sales.salesrpt as "d"
         COLUMNS regno varchar(5) path 'regno/text()',
             dt integer path 'dt/text()',
             product varchar(10) path 'product/text()',
             prize decimal(10,2) path 'prize/text()',
             quantity integer path 'quantity/text()') t2) t3
where t1.regno = t3.regno

REGNO REGENAME      DT     PRODUCT    PRIZE     QUANTITY
----- ------------------- ----------- ---------- ------------ -----------
1   Northern        20091011 ring99      12.55       10
3   Eastern         20091011 bangles     1000.00        1
2   Central         20091015 ring33      50.00        6
1   Northern        20091105 ring99      13.00       10
1   Northern        20091109 ring99      13.52       10
3   Eastern         20091110 ring99      13.50        5

  已選取 6 個記錄。

-- 另外追加測試xml含有多筆資料時的狀況
-- 建立table City,欄位為城市代碼,城市名稱,行政區資料

create table City
(
 cityid  char(2),
 cityname varchar(32),
 cityinfo xml
) in userspace1;

insert into city values
('01','台北市',
'<city>
 <county>
  <id>0101</id>
  <name>松山區</name>
 </county>
 <county>
  <id>0102</id>
  <name>大安區</name>
 </county>
 <county>
  <id>0109</id>
  <name>大同區</name>
 </county>
 <county>
  <id>0110</id>
  <name>中山區</name>
 </county>
 <county>
  <id>0111</id>
  <name>內湖區</name>
 </county>
 <county>
  <id>0112</id>
  <name>南港區</name>
 </county>
 <county>
  <id>0113</id>
  <name>木柵區</name>
 </county>
 <county>
  <id>0114</id>
  <name>景美區</name>
 </county>
 <county>
  <id>0115</id>
  <name>士林區</name>
 </county>
 <county>
  <id>0116</id>
  <name>北投區</name>
 </county>
 <county>
  <id>0117</id>
  <name>信義區</name>
 </county>
 <county>
  <id>0118</id>
  <name>中正區</name>
 </county>
 <county>
  <id>0119</id>
  <name>萬華區</name>
 </county>
 <county>
  <id>0120</id>
  <name>文山區</name>
 </county>
</city>');

-- 行政區xml欄位原為多筆資料時的資料呈現

select cityid,cityname,id,name
from  city,xmltable('for $cty in $d/city/county return $cty'
           passing city.cityinfo as "d"
           columns id varchar(4) path 'id/text()',
           name varchar(16) path 'name/text()') t

CITYID CITYNAME            ID  NAME
------ --------------------------- ---- ----------------
01   台北市             0101 松山區
01   台北市             0102 大安區
01   台北市             0109 大同區
01   台北市             0110 中山區
01   台北市             0111 內湖區
01   台北市             0112 南港區
01   台北市             0113 木柵區
01   台北市             0114 景美區
01   台北市             0115 士林區
01   台北市             0116 北投區
01   台北市             0117 信義區
01   台北市             0118 中正區
01   台北市             0119 萬華區
01   台北市             0120 文山區

  已選取 14 個記錄。

2008年9月5日 星期五

DB2 XML full-text search using NSE


/*
  1)Download/Install Net Search Extender and set variable
  2)Create table and load xml data
  3)db2text start/Enable for text
  4)create index for text
  5)update index
  6)Search Text with function Contain()
  7)db2text stop
*/



-- DB2 是透過 Net Search Extender 對 XML 做 full-text search
-- 先到 IBM 官網去 download Net Search Extender,我的版本是9.5
-- 安裝好之後,先去設定環境變數 DB2DBDFT


直接在 CLP 使用 SET 或
「控制台」→「系統」→「進階」→「環境變數」新增系統變數 DB2DBDFT 並且將值給定為使用的 Database 名稱即可,ex: SAMPLE


※ 不設定的話,會一直出現 CTE0139 環境變數 "DB2DBDFT" 尚未設定。
※ 設定好之後,可以不必下connect database,由 db2text 內部直接做掉。


-- 建立一個測試的 table:ARCHAEOLOGY 來存放考古新聞

CREATE TABLE ARCHAEOLOGY
(
   SNO     INTEGER not null primary key,
   NEWSDATE  CHAR(8),
   NEWS    XML
) IN USERSPACE1;

-- XML 的 layout:

< News >
 < Headline >新聞標題< /Headline >
 < Reporter >記者< /Reporter >
 < Venue >事件發生地點< /Venue >
 < NewAgency >新聞社< /NewAgency > 
 < PublishDate >新聞發布時間< /PublishDate >
 < Content >新聞內容< /Content >
< /News >

-- 抓張圖看一下範例:




-- 直接將我自己準備的 16 則新聞以 xml 的格式儲存
-- 並做一個archaeology.del 檔,內容如下:


1,20070309,< XDS FIL='20070309_1.xml'/ >
2,20070402,< XDS FIL='20070402_1.xml'/ >
3,20070711,< XDS FIL='20070711_1.xml'/ >
4,20070712,< XDS FIL='20070712_1.xml'/ >
5,20070713,< XDS FIL='20070713_1.xml'/ >
6,20070716,< XDS FIL='20070716_1.xml'/ >
7,20070719,< XDS FIL='20070719.xml'/ >
8,20070724,< XDS FIL='20070724_2.xml'/ >
9,20070725,< XDS FIL='20070725_2.xml'/ >
10,20070727,< XDS FIL='20070727_1.xml'/ >
11,20070801,< XDS FIL='20070801_1.xml'/ >
12,20070806,< XDS FIL='20070806_1.xml'/ >
13,20070813,< XDS FIL='20070813_1.xml'/ >
14,20070814,< XDS FIL='20070814_1.xml'/ >
15,20070821,< XDS FIL='20070821_2.xml'/ >
16,20080903,< XDS FIL='20080903_1.xml'/ >

-- import 進去

import from archaeology.del of del xml from c:/ insert into archaeology

-- 用 db2text 將 Net Start Extender 叫起來

db2text start

-- 讓 NSE 對 Database SAMPLE 做 text search

db2text enable database for text connect to sample

-- 用 db2text 對 table archaeology 建 index

db2text create index archaeology_idx for text on archaeology(news)

-- 對 index 做 sync

db2text update index archaeology_idx for text


-- 使用Contain()來找資料
-- 1) 用 like 的方式從整個 xml 裡每一個 element 找包含 Alexan 字眼的文章並將新聞標題列出來


select xmlquery('$ns//Headline' passing news as "ns")
from archaeology
where contains(news,'"Alexan%"') = 1;

-- 結果找到亞歷山大大帝與有關亞歷山卓城的新聞


< Headline >Alexander the Great Conquered City via Sunken Sandbar< /Headline >
< Headline >Hidden City Found Beneath Alexandria< /Headline >
< Headline >Ancient "Lost" City's Remains Found Under Alexandria's Waters< /Headline >

   已選取 3 個記錄。


-- 2) 從整個 xml 裡每一個 element 找包含 Tyre 字眼的文章並將新聞標題列出來


select xmlquery('$ns//Headline' passing news as "ns")
from archaeology
where contains(news,'"Tyre"') = 1;

-- 結果在新聞內容中找到亞歷山大大帝征服推羅古城的新聞


< Headline >Alexander the Great Conquered City via Sunken Sandbar< /Headline >

   已選取 1 個記錄。


-- 找包含 the 這個字的有多少新聞

select count(*)
from archaeology
where contains(news,'"the"') = 1;

-- 結果是全部筆數

1
-----------
     16

   已選取 1 個記錄。


-- 再轉一筆今天的新聞進去
-- a1.del 內如如下


17,20080905,< XDS FIL='20080905.xml' / >

-- import

import from a1.del of del xml from c:\ insert into archaeology;

-- 看一下 archaeology 總筆數

select count(*) from archaeology;

1
-----------
     17

   已選取 1 個記錄。

-- 再找找看包含 the 這個字的有多少新聞
--(20080905.xml確定包含 "the" 這個字)


select count(*)
from archaeology
where contains(news,'"the"') = 1;

-- 結果還是 16 筆

1
-----------
     16

   已選取 1 個記錄。

-- 原因是 index 要做 sync

db2text update index archaeology_idx for text

-- 再找找看包含 the 這個字的有多少新聞

select count(*)
from archaeology
where contains(news,'"the"') = 1;

-- 結果就是 17 筆了

1
-----------
     17

   已選取 1 個記錄。

-- 將 db2text 服務關閉

db2text stop
CTE0001 作業順利完成。

2008年9月2日 星期二

pureXML (II) using DB2 9


/*
  1) register xmlschema
  2) check TARGETNAMESPACE,SCHEMALOCATION
  3) create table with xml datatype
  4) select with explicit validate using target namespace and schema location
  5) insert with explicit validate using target namespace and schema location
*/



-- 做一個xsd,並且指定target namespace
-- 存成 ex: c:\region2.xsd


< ?xml version="1.0"? >
< xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       targetNamespace="http://localhost/region"
       xmlns:r2="http://localhost/region" >
< xsd:element name="region2" >
< xsd:complexType >
< xsd:sequence >
< xsd:element name="regno" type="xsd:string" / >
< xsd:element name="regename" type="xsd:string" / >
< xsd:element name="regcname" type="xsd:string" / >
< /xsd:sequence >
< /xsd:complexType >
< /xsd:element >
< /xsd:schema >


-- register xmlschema
-- 給定schemalocation為http://localhost/region/region2.xsd


register xmlschema 'http://localhost/region/region2.xsd' from c:\region2.xsd as xsd_region2 complete;


-- 從system table: syscat.xsrobjects裡檢查是否已註冊成功
-- check一下 targetnamespace 與 schemalocation 這兩個欄位


select targetnamespace,schemalocation
from  syscat.xsrobjects
where objectname = 'XSD_REGION2';

TARGETNAMESPACE      SCHEMALOCATION
------------------------ ---------------------------------------------------
http://localhost/region http://localhost/region/region2.xsd

  已選取 1 個記錄。



-- 手動建立一個table。
-- 這與oracle不同,oracle在xsd裡的xdb註明xml table後,oracle會自動產生


create table region2
(
    id      integer,
    regioninfo  xml
);


-- 新增前先select並寫好想要使用validate的方式,
-- 這裡使用uri (targetnamespace與schemalocation)來執行validate。
-- (pureXML(I) using DB2 9 指定的是 xmlschema ID來做validate)。


select xmlvalidate(xmlparse(document
      '< ?xml version="1.0" encoding="UTF-8"? >
      < r2:region2 xmlns:r2="http://localhost/region" >
      < regno >1< /regno >
      < regename >Northern< /regename >
      < regcname >北區< /regcname >
      < /r2:region2 >' preserve whitespace)
    according to xmlschema uri 'http://localhost/region'
    location 'http://localhost/region/region2.xsd'
)
from  sysibm.sysdummy1;

-- 得到以下結果,並且未出現錯誤訊息

< r2:region2 xmlns:r2="http://localhost/region" >< regno >1< /regno >< regename >Northern< /regename >< regcname >北區< /regcname >< /r2:region2 >

-- 新增xml data至region2

insert into region2 values
(1,xmlvalidate(xmlparse(document
      '< ?xml version="1.0" encoding="UTF-8"? >
      < r2:region2 xmlns:r2="http://localhost/region" >
      < regno >1< /regno >
      < regename >Northern< /regename>
      < regcname >北區< /regcname>
      < /r2:region2 >' preserve whitespace
     ) according to xmlschema uri 'http://localhost/region'
      location 'http://localhost/region/region2.xsd'));

-- 檢查是否資料新增至region2

select count(*) from region2

1
-----------
      1

  已選取 1 個記錄。

2008年9月1日 星期一

pureXML (I) using DB2 9


/*
  1) register xmlschema
  2) create table with xml datatype
  3) import xml and explicit validate using SQL identifiers as well
*/


-- 首先先將xsd寫好如下 ex:region4.xsd
-- ※ 裡面包含地區代碼/地區英文名稱/地區中文名稱


< ?xml version="1.0"? >
< xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
< xsd:element name="region4" >
< xsd:complexType >
< xsd:sequence >
< xsd:element name="regno" type="xsd:string" / >
< xsd:element name="regename" type="xsd:string" / >
< xsd:element name="regcname" type="xsd:string" / >
< /xsd:sequence >
< /xsd:complexType >
< /xsd:element >
< /xsd:schema >


-- 將xmlschema register進去
-- http://localhost/region4是我給定的xmlschema uri
-- xsd_region4 是這個xmlschema的ID
-- 可下sql檢查是否register成功:
-- select * from syscat.xsrobjects where objectname = 'XSD_REGION4'


register xmlschema 'http://localhost/region4' from c:\region4.xsd as xsd_region4 complete

-- 建立一個有XML資料型態的TABLE

create table region4
(
  id      integer not null,
  regioninfo xml,
  constraint pk_region4 primary key (id)
);


-- 建好之後處理import要使用的檔案
-- 隨便舉例,import 三個xml檔案
-- 1.xml:


< ?xml version="1.0" encoding="UTF-8"? >
< region4 >
< regno >1< /regno >
< regename >Northern< /regename >
< regcname >北區< /regcname >
< /region4 >


-- 2.xml:


< ?xml version="1.0" encoding="UTF-8"? >
< region4 >
< regno >2< /regno >
< regename >Central< /regename >
< regcname >中區< /regcname >
< /region4 >


-- 3.xml:


< ?xml version="1.0" encoding="UTF-8"? >
< region4 >
< regno >3< /regno >
< regename >Southern< /regename >
< regcname >南區< /regcname >
< /region4 >


-- 準備要import的.del檔案。c:\region4.del
-- 用XDS指定


1,< XDS FIL='1.xml'/ >
2,< XDS FIL='2.xml'/ >
3,< XDS FIL='3.xml'/ >

-- 開始import

import from region4.del of del xml from c:/ xmlvalidate using xds default xsd_region4 insert into region4

-- 看結果

select count(*) from region4

1
---------
     3

  已選取 1 個記錄。

-- 全部都是validated過的資料

select count(*) from region4 where regioninfo is validated

1
---------
     3

  已選取 1 個記錄。