Chuẩn bị cho kỳ thi 730 cơ bản về DB2 9, Phần 7: Giới thiệu về XQuery
C. M. Saracco, Kỹ sư phần mềm, IBM 硅谷实验室
Tóm tắt: Các đặc tính DB2® 9 hỗ trợ cho XQuery, một ngôn ngữ chuẩn công
nghiệp được thiết kế cốt để cho việc truy vấn dữ liệu XML. Với XQuery và DB2
9, bạn có thể lấy toàn bộ các tài liệu XML hoặc các phân đoạn XML đã lưu trữ
trong các cột XML. Bạn cũng có thể chỉ rõ các bộ lọc dựa trên XML cho các truy
vấn, chuyển đổi đầu ra XML và kết hợp các điều kiện logic vào các truy vấn. Bài
viết này hướng dẫn cho bạn hỗ trợ XQuery của DB2, giải thích vài khái niệm ngôn
ngữ cơ bản và chỉ ra bạn có thể viết và thực hiện các câu truy vấn XQuery đơn
giản đối với dữ liệu XML đã lưu trữ trên DB2 như thế nào. Đây là bài viết thứ bẩy
trong loạt bẩy bài viết giúp bạn chuẩn bị cho bài thi 730 cơ bản về DB2 9.
Trước khi bạn bắt đầu
Để giúp bạn chuẩn bị cho các bài thi lấy chứng chỉ DB2, bài viết này giới thiệu
cho bạn về XQuery và những hỗ trợ của nó trong DB2. Bạn nên làm quen với
DB2 9 và hỗ trợ pureXML của nó trước khi đọc bài viết này.
Bài viết này tập trung vào việc sử dụng XQuery để truy vấn dữ liệu DB2 XML.
Bài viết đưa ra một thảo luận hạn chế về việc sử dụng SQL/XML (SQL với những
mở rộng XML) để truy vấn dữ liệu DB2 XML. Để tìm hiểu kỹ hơn về những hỗ
trợ của DB2 cho các hàm SQL/XML theo chuẩn kỹ nghệ, xem Tài nguyên.
Về loạt bài viết này
Bạn đang muốn thi lấy chứng chỉ cơ bản về DB2 (Bài thi 730)? Nếu đúng, bạn đã
tìm đúng nơi để học rồi đấy. Loạt bài này nằm trong loạt bẩy bài viết chuẩn bị thi
chứng chỉ DB2 bao hàm tất cả kiến thức cơ bản các chủ đề bạn cần nắm được
trước khi đọc câu hỏi thi đầu tiên. Thậm chí, nếu bạn không có ý định thi lấy
chứng chỉ ngay bây giờ, thì tập hợp bài viết này vẫn sẽ là một kho tài nguyên hữu
ích để bắt đầu học và tìm hiểu xem có những gì mới trong DB2 9. Về bài viết này
Bài viết này khảo sát các khả năng cơ bản hỗ trợ XQuery mới của DB2. Ngoài ra,
bài viết cũng phân tích những khác biệt chính giữa XQuery và SQL, khảo sát
nền Windows. Bạn sẽ lĩnh hội được nhiều kiến thức hơn nếu bạn tải về phiên bản
dùng thử miễn phí của IBM DB2 9 để làm việc với bài viết này. Tổng quan về XQuery
DB2 9 có khả năng hỗ trợ XQuery, một ngôn ngữ truy vấn mới được thiết kế
chuyên dụng khi thao tác với dữ liệu XML. Là một phần của chuẩn kỹ nghệ W3C,
XQuery cho phép người dùng duyệt cấu trúc phân cấp trong tài liệu XML. Kết quả
là, bạn có thể truy vấn các tài liệu XML hoặc các phân đoạn tài liệu sử dụng
XQuery. Bạn cũng có thể viết các câu XQuery có chứa các vị từ dựa trên XML để
lọc ra dữ liệu không mong muốn từ những kết quả mà DB2 sẽ trả về. XQuery hỗ
trợ nhiều khả năng như khả năng biến đổi đầu ra XML và kết hợp logic điều kiện
vào các truy vấn.
Trước khi học cách sử dụng XQuery như thế nào, bạn cần hiểu vài khái niệm cơ
bản về ngôn ngữ.
Cơ bản về XQuery
Một XQuery luôn biến đổi từ một giá trị của mô hình dữ liệu XQuery này
(XQuery Data Model) sang một giá trị của một mô hình dữ liệu XQuery khác. Một
giá trị trong mô hình dữ liệu XQuery là một chuỗi gồm không hoặc nhiều hơn một
danh mục (item). Một danh mục có thể là:
Giá trị nguyên tử bất kì
Một nút XML như phần tử (element), thuộc tính (attribute) hoặc nút văn
bản (text node) (đôi khi được gọi là một phân đoạn tài liệu XML)
Một tài liệu XML đầy đủ
Thường thì đầu vào một XQuery là một tập hợp các tài liệu XML.
Ví dụ 1 biểu diễn một tài liệu XML có chứa 8 nút phần tử, một nút thuộc tính và
sáu nút văn bản. Các nút phần tử được biểu diễn bằng các thẻ phần tử. Các phần tử
Client, Address, street, city, state, zip và hai phần tử email được gọi là các nút
phần tử trong tài liệu này. Nếu để ý kỹ phần tử Client, bạn sẽ thấy rằng nó chứa
một nút thuộc tính là id của Client đó. Một số nút phần tử của tài liệu có các nút
Cho phép người dùng trình duyệt hoặc "khám phá" cấu trúc phân cấp của
một tài liệu XML và trả về các nút được tìm thấy khi kết thúc đường dẫn.
Biểu thức FLWOR
Rất giống với biểu thức SELECT-FROM-WHERE trong SQL. Nó được
dùng để thực hiện phép lặp trên một chuỗi các danh mục và trả về một vài
kết quả nào đó được tính toán từ mỗi danh mục. XQuery khác với SQL như thế nào
Nhiều người dùng SQL nhận thức sai lầm rằng XQuery rất giống với SQL. Tuy
nhiên, XQuery khác SQL ở rất nhiều điểm lớn bởi vì ngôn ngữ này được thiết kế
để thao tác với các mô hình dữ liệu có nhiều đặc trưng khác biệt. Các tài liệu XML
có cấu trúc phân cấp và có tính chất thứ bậc. Ngược lại, các bảng biểu được hỗ trợ
trong hệ quản trị cơ sở dữ liệu (DBMS) quan hệ (nói chính xác hơn là DBMS dựa
trên SQL) là cấu trúc phẳng và dựa trên tập hợp, do đó các bản ghi là không có thứ
tự.
Những sự khác biệt này trong các mô hình dữ liệu dẫn tới sự khác biệt quan trọng
trong các ngôn ngữ truy vấn được thiết kế để hỗ trợ mô hình đó. Ví dụ, XQuery
cho phép người lập trình duyệt trên cấu trúc phân cấp của tài liệu XML. SQL
phẳng (không có các mở rộng XML) không có hoặc không cần thiết các biểu
thức tương ứng để duyệt trên cấu trúc dữ liệu bảng biểu như vậy. XQuery hỗ trợ
cả hai loại dữ liệu có kiểu và không có kiểu, trong khi dữ liệu SQL luôn luôn phải
được định kiểu rõ ràng.
Đây chỉ là một vài sự khác biệt giữa XQuery và SQL. Việc cung cấp một danh
sách đầy đủ những sự khác biệt giữa hai ngôn ngữ nằm ngoài phạm vi của bài viết
có tính chất giới thiệu này, nhưng phần Tài nguyên sẽ cung cấp thêm thông tin về
chủ đề này.
XQuery không có giá trị null bởi vì các tài liệu XML bỏ qua dữ liệu thiếu hoặc dữ
liệu không biết. SQL lại sử dụng giá trị null để biểu diễn những dữ liệu dạng đó.
XQuery trả về một chuỗi dữ liệu XML; trong khi SQL trả về kết quả là các tập
có thể viết:
Ví dụ 3. Duyệt phần tử email đầu tiên
/Client/email[1]
Ngoài việc xác định các nút phần tử trong các biểu thức đường dẫn, bạn có thể xác
định các nút thuộc tính sử dụng kí hiệu @ để phân biệt thuộc tính với phần tử.
Biểu thức đường dẫn này duyệt phần tử email đầu tiên với điều kiện phần tử Client
có chứa thuộc tính id là 123:
Ví dụ 4. Xác định một nút thuộc tính và giá trị
/Client[@id='123']/email[1]
Ví dụ trước kết hợp một vị từ lọc dựa trên một giá trị thuộc tính. Bạn cũng có thể
lọc trên các giá trị nút khác. Những người dùng XPath cũng khá thường xuyên lọc
trên các giá trị phần tử như trong ví dụ 5, nó trả về phần tử mã bưu điện (zip) với
mọi Client sống ở California:
Ví dụ 5. Lọc trên một giá trị phần tử
/Client/Address[state="CA"]/zip
Bạn cũng có thể dùng dấu sao ("*") để tham chiếu nút bất kì ở từng bước riêng của
biểu thức đường dẫn. Ví dụ sau trả về phần tử city bất kì tìm thấy dưới nút con gần
nhất bất kì của phần tử Client.
Ví dụ 6. Sử dụng dấu sao (*)
/Client/*/city
Cho trước tài liệu mẫu của chúng ta, truy vấn trên trả về phần tử city với một giá
XQuery, trong đó nó biểu diễn những trường hợp khác mà XQuery khác với SQL.
Ví dụ, nếu bạn kết hợp biểu thức đường dẫn "/client/address" vào câu XQuery của
bạn, bạn không nhận được bất kì kết quả nào với tài liệu mẫu đã cho trong Ví dụ
1. Các biểu thức FLWOR trong XQuery
Mọi người thường dùng các biểu thức FLWOR trong XQuery. Giống như khối
SELECT-FROM-WHERE trong SQL, một biểu thức FLWOR của XQuery có thể
chứa nhiều mệnh đề được xác định bằng các từ khóa. Các mệnh đề của một biểu
thức FLWOR bắt đầu bằng các từ khóa dưới đây:
for: Lặp trên một chuỗi đầu vào, liên kết lần lượt một biến với mỗi danh
mục (item) đầu vào.
let: Khai báo một biến và gán cho nó một giá trị, có thể là một danh sách
các mục.
where: Xác định điều kiện để lọc các kết quả truy vấn
order by: Xác định trật tự sắp xếp kết quả
return: Xác định kết quả được trả về
Hãy xem lại mỗi từ khóa một lúc. Chúng ta sẽ thảo luận về mệnh đề for và return
đồng thời, vì vậy bạn có thể quan sát một ví dụ đầy đủ. (Không có mệnh đề return,
biểu thức sẽ không đầy đủ.)
for và return
Các từ khóa for và return thường sử dụng lặp qua một chuỗi các giá trị và
trả về kết quả nào đó cho mỗi giá trị. Sau đây là một ví dụ rất đơn giản:
for $i in (1, 2, 3)
return $i
Trong XQuery, các tên biến được thêm một dấu ("$") đằng trước. Vì vậy ví
dụ trên gán các giá trị 1, 2, 3 vào biến $i ở mỗi lần lặp, và trả về mỗi giá trị
cho $i trong mỗi lần lặp đó. Kết quả của biểu thức là một chuỗi ba giá trị:
<output>1 2 3</output>
Kết quả tương đối khác. Nó chứa một phần tử đầu ra đơn với giá trị "1 2 3".
Hai ví dụ này minh họa điều quan trọng cần ghi nhớ là: từ khóa for lặp qua
các mục trong một chuỗi đầu vào ở mỗi lần lặp thì gán cho chúng mỗi biến
cụ thể. Ngược lại, từ khóa let gán tất cả các mục trong chuỗi đầu vào một
lần một biến cụ thể.
where
Trong XQuery, các hàm where rất giống với mệnh đề WHERE trong SQL:
nó cho phép bạn áp dụng các điều kiện lọc trên truy vấn của mình. Xem ví
dụ sau đây:
for $i in (1, 2, 3)
where $i < 3
return <output>{$i}</output> <output>1</output>
<output>2</output>
order by
Cho phép bạn xác định các kết quả trả về theo một trật tự. Hãy xem biểu
thức XQuery đơn giản sau đây và đầu ra của nó (không sắp xếp theo bất kì
trật tự nào được xác định người dùng):
for $i in (5, 1, 2, 3)
return $i
5
1
2
cả các truy vấn được trình bày ở đây sẽ được viết với phần mở đầu bằng xquery.
Môi trường cơ sở dữ liệu mẫu
Để giúp bạn học XQuery, bài viết này đưa ra một bảng "clients" mẫu có chứa một
vài tài liệu XML. Các đoạn tiếp theo giải thích chi tiết hơn về bảng này và nội
dung của nó, mô tả những tiện ích mà DB2 cung cấp để bạn có thể sử dụng viết
các câu XQuery.
Nếu bạn muốn cài đặt hệ thống DB2 của mình có chứa các nội dung và bảng mẫu
thì một kịch bản sẵn có là tutorial.sql. Nó chứa tất cả các mã trình bày trong phần
này.
Bảng mẫu
Bảng "clients" trong các ví dụ của chúng ta có chứa các cột dựa trên các kiểu dữ
liệu SQL truyền thống (chẳng hạn như số nguyên và các xâu kí tự độ dài khác
nhau), và một cột dựa trên kiểu dữ liệu SQL mới là "XML".
Ba cột đầu tiên ghi thông tin về các ID, tên (name) và trạng thái (status) của các
khách hàng (Client). Các giá trị điển hình cho cột status bao gồm Gold, Silver, và
Standard. Cột thứ tư chứa mỗi thông tin liên lạc của khách hàng, chẳng hạn như
địa chỉ hộp thư nhà riêng (home mailing address), số điện thoại (phone numbers),
địa chỉ email (email addresses), v.v Các thông tin như thế được lưu trữ trong các
tài liệu XML đã cấu trúc.
Bảng "Clients" được định nghĩa như thế nào:
Ví dụ 9. Định nghĩa bảng Clients
create table clients(
id int primary key not null,
name varchar(50),
status varchar(10),
contactinfo xml
);
'<Client>
<Address>
<street>1204 Meridian Ave.</street>
<apt>4A</apt>
<city>San Jose</city>
<state>CA</state>
<zip>95124</zip>
</Address>
<phone>
<work>4084440000</work>
</phone>
<fax>4085555555</fax>
</Client>'
); insert into clients values (9077, 'Lisa Hansen', 'Silver',
'<Client>
<Address>
<street>9407 Los Gatos Blvd.</street>
<city>Los Gatos</city>
<state>CA</state>
<zip>95032</zip>
</Address>
<phone>
<home>4083332222</home>
</phone>
</Client>'
);
<email></email>
</Client>'