• SQL Kiwi (1/26/2012)


    ...

    For anyone that wants to play with the XML, I think this is about right:

    DECLARE @x xml =

    N'<toys>

    <myToy>

    <name>Train</name>

    <components>

    <part><name>engine</name><howMany>1</howMany></part>

    <part><name>coaches</name><howMany>10</howMany></part>

    <part><name>caboose</name><howMany>1</howMany></part>

    <part><name>tracks</name><howMany>125</howMany></part>

    <part><name>switches</name><howMany>8</howMany></part>

    <part><name>power controller</name><howMany>1</howMany></part>

    </components>

    </myToy>

    <myToy>

    <name>remote control car</name>

    <components>

    <part><name>remote control</name><howMany>1</howMany></part>

    <part><name>car</name><howMany>1</howMany></part>

    <part><name>batteries</name><howMany>8</howMany></part>

    </components>

    </myToy>

    </toys>

    ';

    Right as in accurate yes. Right as in correct is a matter of opinion. Elements should not be used for properties that occur 0 or 1 times and are expressible as attributes. In my opinion, a more correct form for this XML would be:

    DECLARE @x xml =

    N'<toys>

    <myToy name="Train">

    <components>

    <part name="engine" howMany="1" />

    <part name="coaches" howMany="10" />

    <part name="caboose" howMany="1" />

    <part name="tracks" howMany="125" />

    <part name="switches" howMany="8" />

    <part name="power controller" howMany="1" />

    </components>

    </myToy>

    <myToy name="remote control car">

    <components>

    <part name="remote control" howMany="1" />

    <part name="car" howMany="1" />

    <part name="batteries" howMany="8" />

    </components>

    </myToy>

    </toys>

    ';

    Note how much shorter (464 instead of 636 characters, not counting whitespace) and cleaner that XML is. It's the unrelenting insistence of some to express every property in XML as an element that leads to XML being widely considered a waste of space and difficult to read. It doesn't have to be either.

    (Of course, the SQL would have to be modified to address attributes instead of elements, e.g:

    select

    t.c.value('../../@name','VARCHAR(20)') name,

    t.c.value('@name','VARCHAR(20)') componentname,

    t.c.value('@howMany','tinyint') numberOfItems

    from @x.nodes('toys/myToy/components/part') t(c)

    (edit: as a side note, running this query on the attribute-based XML in the same batch as the comparable query on the element-heavy XML and returning the query plan shows that the attribute-based XML query used 28% of the query cost, vs 72% for the element-heavy XML -- so it appears to be more efficient as well (tested on 2005 64-bit developer edition))

    )

    Okay, I'm done ranting.