SQL/XML nested child problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • engelenfrederik@gmail.com

    #1

    SQL/XML nested child problem

    Hello all,

    I ran into an interesting SQL/XML question yesterday. A customer wants
    to make a part of the relational data available through a webservice
    as XML. This seemed like the perfect opportunity to use the DB2 XML-
    capabilities. The following test scenario will make things easier to
    explain:

    drop table test.customer;
    create table test.customer
    (
    id integer not null,
    name varchar(255) not null,
    email varchar(255),
    customer_type char(1),
    contact_of_cust omer_id integer, -- points to a custom from whom this
    custom is a contact
    primary key(id)
    );

    insert into test.customer(i d, name, email, customer_type,
    contact_of_cust omer_id) values (1, 'name1', '1@1.com', 'A', null), (2,
    'name2', '2@2.com', 'A', null), (3, 'name3', '2@2.com', 'B', 2), (4,
    'name4', '4@4.com', 'C', 2);

    The database structure allows for customers to have contacts (which in
    turn are customers as well, etc). In practice, the application will
    allow only one level of contacts, so no recursion is required. As you
    can see, customer 1 and 2 are of the required type 'A', 1 having no
    contacts, 2 having customers 3 and 4 as contact.

    The XML should contain a list of customers (including their details),
    and each one that has contacts should have them listed as child nodes.
    This gives the following (the output format is fixed, I can't change
    it):

    <customers>
    <customer>
    <customerId>1 </customerId>
    <customerInfo >
    <customerName>n ame1</customerName>
    <customerEmail> 1@1.com</customerEmail>
    </customerInfo>
    </customer>
    <customer>
    <customerId>2 </customerId>
    <customerInfo >
    <customerName>n ame2</customerName>
    <customerEmail> 2@2.com</customerEmail>
    </customerInfo>
    <customerContac t>
    <customerId>3 </customerId>
    <customerInfo >
    <customerName>n ame3</customerName>
    <customerEmail> 2@2.com</customerEmail>
    </customerInfo>
    </customerContact >
    <customerContac t>
    <customerId>4 </customerId>
    <customerInfo >
    <customerName>n ame4</customerName>
    <customerEmail> 4@4.com</customerEmail>
    </customerInfo>
    </customerContact >
    </customer>
    </customers>

    I've created the following xquery that returns one record containing
    the neccesary XML:

    XQUERY
    let $customers := db2-fn:sqlquery(
    "
    select
    XMLELEMENT
    (
    NAME ""customer" ",
    XMLELEMENT
    (
    NAME ""customerI d"",
    cust.id
    ),
    XMLELEMENT
    (
    NAME ""customerInfo" ",
    XMLFOREST
    (
    cust.name as ""customerName" ",
    cust.email as ""customerEmail ""
    )
    ),
    XMLAGG
    (
    XMLELEMENT
    (

    NAME ""customerConta ct"",
    XMLELEMENT
    (
    NAME ""customerI d"",
    cont.id
    OPTION NULL ON NULL
    ),
    XMLELEMENT
    (
    NAME ""customerInfo" ",
    XMLFOREST
    (
    cont.name as ""customerName" ",
    cont.email as ""customerEmail ""
    )
    OPTION NULL ON NULL
    )
    OPTION NULL ON NULL
    )
    )
    )

    from test.customer cust
    left outer join test.customer cont on cont.contact_of _customer_id =
    cust.id
    where cust.customer_t ype = 'A'
    group by cust.id, cust.name, cust.email
    ")

    return
    <customers>{$cu stomers}</customers>;

    It selfjoins customer (cust and cont) and groups by the fields in
    cust. The XMLAGG function does the rest. This was based on the example
    used in the SQL Reference Vol.1: XMLELEMENT, regarding the
    departments.

    The query functions correctly. Notice however the GROUP BY-statement
    at the end of it. The real table contains much more data, including
    data from other tables as well. With this query, I have to GROUP BY on
    every column I want to include in customer. This seems unnecessary and
    wasteful. I am sure that there is a better way to write this one.

    XQuery guru's (and even lesser gods), I would like to ask you to take
    your best shot at it.

    Many thanks in advance,

    Frederik
Working...