1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle XSQL- P15 pptx

20 150 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Retrieving Xml
Trường học Oracle University
Chuyên ngành Database Management
Thể loại Bài tập tốt nghiệp
Năm xuất bản 2023
Thành phố Redwood City
Định dạng
Số trang 20
Dung lượng 416,32 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The first tool you’ll examine is the xsql:include-owa action, which allows you to write XML into the XSQL result.. This allows you to easily store and query XML doc-uments stored in Orac

Trang 2

Oracle can store any media type in the database—XML is no exception In the previous pages, you saw how to query against XML documents stored in the database This sec-tion examines how to return XML—as opposed to strings—into your XSQL The first tool you’ll examine is the xsql:include-owa action, which allows you to write XML into the XSQL result Next, you’ll learn about the XMLGEN utility It essentially allows you to do what XSQL does—generate XML based on a SQL query The difference is that you can generate XML from inside a PL/SQL procedure The last section covers a new feature of Oracle 9i—the XMLType This allows you to easily store and query XML doc-uments stored in Oracle Before beginning the lessons, it’s important to understand what is hard about retrieving XML with XSQL The first section covers these difficulties

What’s So Hard?

In the previous section on Oracle Text, you saw that it is quite easy to store XML in the table Just insert it like any other text The size of our test documents was limited, but that is easily remedied—just use a CLOB type and you can store gigabytes of XML You might be wondering, “Can’t you just select the text?”

Retrieving XML

11

Trang 3

Well, you can, but not with the xsql:query action Consider the following XSQL:

<?xml version=”1.0”?>

<page connection=”demo” xmlns:xsql=”urn:oracle-xsql”>

<xsql:query>

SELECT text

FROM docs_table

WHERE contains(text,’software INPATH (/article/body)’)>0

</xsql:query>

</page>

It will execute easily enough and return the result shown in Figure 11.1

It looks like XML, so what’s the problem? Upon closer examination, you’ll see that the XML returned by the query isn’t XML at all! Notice that Internet Explorer didn’t render it with the customary colored tags When you look at the source, you’ll see that all of the essential XML characters have been escaped and replaced with their URL-encoded equivalents

What a shame! In the context of this example, it seems that you have uncovered a horrible failing of XSQL But it isn’t, really XSQL’s default behavior is to assume that XML isn’t being returned Thus, it’s proper and required to escape the special XML characters As you’ll see, the workarounds are pretty easy In this chapter, you’ll learn about the PL/SQL-based workaround You can also retrieve XML with the help of cus-tom XSQL action handlers, as you’ll see in Chapter 18, “Cuscus-tom Action Handlers.”

Figure 11.1 Result of retrieving XML with xsql:query.

Trang 4

Creating XML with xsql:include-owa

In Chapter 5, “Writing XSQL Pages,” you learned that you could use the xsql: include-owato include XML of your own choosing in your result At that point, PL/SQL hadn’t been covered, so you couldn’t explore this action in detail Now you can Here you’ll learn how to use the htp.print PL/SQL procedure to write XML of your own choosing to the XSQL datagram

First, however, you need to cover a little background Oracle provides two packages, (1) htp and (2) htf, that have a series of procedures and functions, respectively The original purpose of these was to allow PL/SQL developers to easily create Web appli-cations For each HTML element there is both a wrapper procedure and wrapper func-tion This XSQL executes the wrapper procedure for the italic tag

<?xml version=”1.0”?>

<page connection=”demo” xmlns:xsql=”urn:oracle-xsql”>

<xsql:include-owa>

htp.italic(htf.bold(‘hello’));

</xsql:include-owa>

</page>

This will produce the output seen in Figure 11.2 The <I> tags are included in our XML result, and the angle brackets weren’t replaced with &lt; and &gt; How do the htpand htf procedures escape escaping? The procedures in the htp package write to the server-side page buffer

Figure 11.2 Result of htp.italic and htf.bold.

Trang 5

Here’s how the htp procedures and htf functions are able to get the angle brackets all the way through to the browser:

■■ The htf functions wrapper their argument with the appropriate tags and return the resultant string In this case, hello is wrappered and

<b>hello</b>is returned

■■ The htp procedures also wrapper their argument In this case, the wrappering produces <i><b>hello</b></i>

■■ Instead of returning anything, the htp procedures write their result to the server-side page buffer

■■ The xsql:include-owa action reads the contents of the server-side page buffer and writes those to the output without escaping the reserved XML characters

In all likelihood, you don’t have any interest in using the htp and htf subprograms

to generate HTML for your XSQL (If you do have a strong interest in creating such an architecture, consider taking a head-clearing walk There be dragons!) From an XSQL standpoint, there is really one subprogram of interest—htp.print

The htp.prn procedure allows you to print an arbitrary string to the server-side page buffer without a trailing carriage return (If you want a trailing carriage return, use htp.print.) You aren’t limited solely to HTML tags, and all of the angle brackets will stay intact The following procedure works this magic:

CREATE OR REPLACE PROCEDURE get_doc_xml IS

doc_xml docs_table.text%TYPE;

CURSOR doc_cursor IS

SELECT text FROM docs_table WHERE

contains(text,’software INPATH (/article/body)’)>0;

BEGIN

htp.prn(‘<article-set>’);

OPEN doc_cursor;

LOOP

FETCH doc_cursor INTO doc_xml;

EXIT WHEN doc_cursor%NOTFOUND;

htp.prn(doc_xml);

END LOOP;

htp.print(‘</article-set>’);

END;

The procedure selects the articles that have the word “software” inside the body ele-ment of the XML docuele-ments Before looping through the cursor, a start tag for the root element is printed to the buffer This is required because the xsql:include-owa will return an error if the XML that you write isn’t well formed In the loop itself, each doc-ument is written to the buffer and the loop exits at the end of the cursor The final step

is to close the root element The procedure can be called with the following XSQL:

<?xml version=”1.0”?>

<page connection=”demo” xmlns:xsql=”urn:oracle-xsql”>

Trang 6

</xsql:include-owa>

</page>

The result is an XML document that contains two XML documents stored in the database, as shown in Figure 11.3

In our example, the query was hard coded As you learned earlier, however, you can easily make the queries completely dynamic and based on user input

Generating XML from PL/SQL

From the previous section, you saw how to write a particular data field as XML Of course, you can use the same methodology to create quite complex XML documents and write them to the XSQL output If you want to do this, there are a couple of PL/SQL packages that can help you These are discussed in this section They allow you to do exactly what XSQL does, but from inside a procedure This raises the obvi-ous and valid architectural question: Why would you want to generate XML from inside PL/SQL for consumption by XSQL? We’ll look at these valid concerns after learning a bit about the helper code available Oracle 9i users can use the DBMS_QUERY package, while Oracle 8i users can use the XMLGEN package

Figure 11.3 XML documents in XSQL results.

Trang 7

For Oracle 9i, the DBMS_QUERY package will XML-ify a query into a CLOB variable You then break the CLOB into strings that can be passed to the http.prn procedure

CREATE OR REPLACE PROCEDURE use_dbms_xmlgen IS

ctx dbms_xmlgen.ctxhandle;

result_clob CLOB;

output_var VARCHAR2(4000);

offset_var INTEGER :=1;

buf_size INTEGER:=4000;

BEGIN

ctx:=dbms_xmlgen.newContext(‘SELECT * FROM emp’);

result_clob:=dbms_xmlgen.getXML(ctx);

WHILE offset_var < dbms_lob.getlength(result_clob) LOOP

DBMS_LOB.READ(result_clob,buf_size,offset_var,output_var); htp.prn(output_var);

offset_var:=offset_var+4000;

END LOOP;

END;

You call this procedure with the following XSQL:

<?xml version=”1.0”?>

<page connection=”demo” xmlns:xsql=”urn:oracle-xsql”>

<xsql:include-owa>

use_dbms_xmlgen;

</xsql:include-owa>

</page>

At the Oracle 8i level, the code is slightly different: It doesn’t use contexts, and the SQL statement can be handed directly to the getXML procedure However, the XMLGEN package has been deprecated Oracle 9i users should use the DBMS_XMLGEN package instead

CREATE OR REPLACE use_xmlgen IS

result_clob CLOB;

output_var VARCHAR2(4000);

offset_var INTEGER :=1;

buf_size INTEGER:=4000;

BEGIN

result_clob:=xmlgen.getXML(‘SELECT * FROM emp’);

WHILE offset_var < dbms_lob.getlength(result_clob) LOOP

DBMS_LOB.READ(result_clob,buf_size,offset_var,output_var); htp.prn(output_var);

offset_var:=offset_var+4000;

END LOOP;

END;

Trang 8

In both of these cases, your result is going to look exactly the same as if you executed the SQL using the xsql:query element The XML generated using these APIs is also

in the canonical format

So, for these simple examples, you’ve done a lot of work in order to do what XSQL does anyway! In general, if you can get the same result using a straight XSQL query, then you probably should Of course, with this methodology you can apply a lot of procedural logic, as you did with reference cursors a few pages ago But then, you can probably accomplish the same logic using the xsql:ref-cursor-function action

It works great any time you wish to procedurally create the SQL statement whose results you want in XML And again, if you can get the same result using xsql:ref -cursor-function, then you should employ that action instead

There are some cases where you will find use for the DBMS_XMLGEN (or XMLGEN) packages at the PL/SQL level The key advantage is that you can assemble your XML

at a very atomic level and have great control over it You can dynamically select exactly the XML elements you wish to put into the output and base those decisions on any data you can access in the database If you need to grab a couple of rows from the database, you can put them into the output with the htp.prn procedure discussed earlier

However, it’s important to remember that the DBMS_XMLGEN (or XMLGEN) packages used in this way are just one tool in your toolbox You should probably keep it in the bottom of your toolbox and reach for xsql:query and xsql:ref-cursor -function Also, you should understand action handlers before basing too much code on this approach An action handler can also give you fine-grained control over the XML, as well as give you more precise ways of handling elements than the approach described here

XMLType

In our earlier example with Oracle Text, you stored the XML as a simple string Oracle 9i users can also store documents using the XMLType The XMLType gives you much more power over your XML than you have with simple strings There are two ways to use XMLType: (1) You can create an XMLType object at runtime based on a string or clob, or (2) you can create a column in the database of XMLType Having an XMLType

as a column is more efficient, so you’ll learn about this method first However, it’s often impractical to do this, especially if you are working with existing database schemas You’ll see how to construct and use the XMLType dynamically, also This section con-cludes by detailing all the procedures and functions you can use in conjunction with XMLType

Here is how you get started Your first step is to create a table that has an XMLType column You can do that as follows:

CREATE TABLE XMLType_table(

ID NUMBER,

DOC_NAME VARCHAR2(20),

xml_doc SYS.XMLTYPE);

Trang 9

Now you want to put some data in to your table The only difference between this insert and the plain-text insert is the call to sys.XMLType.createXML This changes the string data into the XMLType

INSERT INTO XMLType_table (id,doc_name,xml_doc) VALUES (1,’doc1’,

sys.XMLType.createXML(‘<article>

<subject>networking</subject>

<title>Networking Basics</title>

<body> People didn’’t notice the first fax machine The second

infinitely increased the value of both </body>

</article>’)

);

INSERT INTO XMLType_table(id,doc_name,xml_doc) VALUES (2,’doc2’,

sys.XMLType.createXML(‘<article>

<subject>software</subject>

<reference>Mythical Man Month, Dr Fred Brooks</reference>

<title>Brook’’s Law</title>

<body>Putting more people on a late software project makes it

later.</body>

</article>’)

);

As before, you have to create an index on your column, and you’ll have to update it every time that you update the data However, you don’t have to create a section group first Oracle already knows it’s dealing with XML

CREATE INDEX XMLType_index ON XMLType_table(xml_doc)

INDEXTYPE IS ctxsys.context;

At this point, you can do all of the types of searches that you did earlier with Oracle Text Here is one example:

SELECT xml_doc

FROM XMLType_table

WHERE contains(xml_doc,’people INPATH (/article/body)’)>0;

Using the xsql:include-owa action, you can also use the htp.prn technique to push the document into the XSQL output In this particular case, the documents are less than 4,000 characters, so you can use the getStringVal function However, if the documents are larger, a runtime error would be generated If there may be documents longer than 4,000 characters, you would have to iterate through a CLOB, as you did in the previous section

CREATE OR REPLACE get_XMLType_xml IS

xml_doc_str VARCHAR2(4000);

CURSOR doc_cursor IS

Trang 10

SELECT a.xml_doc.getStringVal()

FROM XMLType_table a

WHERE CONTAINS(xml_doc,’people INPATH (/article/body)’)>0;

BEGIN

htp.print(‘<article-set>’);

OPEN doc_cursor;

LOOP

FETCH doc_cursor INTO xml_doc_str;

EXIT WHEN doc_cursor%NOTFOUND;

htp.prn(xml_doc_str);

END LOOP;

htp.print(‘</article-set>’);

END;

At this point, you haven’t done anything more than you did when the XML was just plain text The following example takes you into new territory The extract function allows you to pull just the nodes you want from the document By simply altering our cursor statement as follows:

CURSOR doc_cursor IS

SELECT a.xml_doc.extract(‘/article/subject’).getStringVal()

FROM XMLType_table a

WHERE CONTAINS(xml_doc,’people INPATH (/article/body)’)>0;

you can get a result that just returns the subject nodes But the getStringVal is still limited to 4,000 characters If the node that you’re extracting (including the text, all the children, and all of the tags) contains more than 4,000 characters of data, a runtime error will be raised

With this simple SELECT statement you are solving a complex problem very ele-gantly The relational model is great at storing structured data, such as a company’s payroll or accounts receivable, but has a hard time with unstructured document data XML is great for formatting documents, but it is complex to store and search across sets

of XML documents By storing XML documents in the Oracle database, you get all of the benefits of the relational model plus the backup, recovery, and performance afforded by Oracle By using Oracle Text in conjunction with the XMLType, you can easily search the documents and extract the nodes that you want You’ll be seeing more

of this lucrative combination in Chapter 14, “Building XSQL Web Applications,” when you build your first XSQL application from scratch

N OT E The extract function, along with several other functions and

procedures of XMLType, uses XPath to search the document You’ll learn more

about XPath in the next chapters.

In this case, you had XMLType set up at the database level You can also instantiate XMLTypeat runtime In the following example, you return to the docs_table used in the original examples of Oracle Text In that table, the XML is stored simply as a

Ngày đăng: 03/07/2014, 08:20

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN