I get sulky when...
May. 25th, 2006 03:19 pmI'm in training at the moment on SQL server. I'm sulky at the moment too. Why? The trainer asked a question with what I thought was an obvious answer. I answered and was told I was wrong. Lots of other people answered and they were wrong too. When she told us the answer I discovered that I was actually right, she just hadn't quite understood what I said. This has made me sulky. On the other hand though I can be amused because I think I might understand this part of the course better than the trainer. Certainly soem of the explanations have been a little unclear in my mind.
Ah, well. Back to the training....
Edit:
The question was as follows (this is an abdridged version but keeps the core facts). For those that care I'm doing MS course 2779A.
I have the following XML:
I then do the following SQL:
Why do I not need to specify where Quantity gets its value from as I did for InvoiceID and ProductID?
Second edit: Explain in the above SQL what the '/SalesInvoice/Items/Item' means. The trainer did so *very* badly in my view and I want to see if those who know (probably Dave mainly) can explain better. :) Those who don't know are welcome to guess if they want. They are allowed to ask what the recordset returned looks like too if they want though.
Ah, well. Back to the training....
Edit:
The question was as follows (this is an abdridged version but keeps the core facts). For those that care I'm doing MS course 2779A.
I have the following XML:
<?xml version="1.0" ?>
<SalesInvoice InvoiceID="1000" CustomerID="123" OrderDate="2004-03-07">
<Items>
<Item ProductCode="12" Quantity="2" UnitPrice="12.99">aaa<ProductName>Bike</ProductName></Item>
<Item ProductCode="41" Quantity="1" UnitPrice="17.45">bbb<ProductName>Helmet</ProductName></Item>
<Item ProductCode="2" Quantity="1" UnitPrice="2.99">ccc<ProductName>Water Bottle</ProductName></Item>
</Items>
</SalesInvoice>
I then do the following SQL:
SELECT * FROM
OPENXML(@docHandle, '/SalesInvoice/Items/Item', 1)
WITH
(InvoiceID int '../../@InvoiceID',
ProductID int '@ProductCode',
Quantity int
)
Why do I not need to specify where Quantity gets its value from as I did for InvoiceID and ProductID?
Second edit: Explain in the above SQL what the '/SalesInvoice/Items/Item' means. The trainer did so *very* badly in my view and I want to see if those who know (probably Dave mainly) can explain better. :) Those who don't know are welcome to guess if they want. They are allowed to ask what the recordset returned looks like too if they want though.
(no subject)
Date: 2006-05-25 02:26 pm (UTC)I wanna know if I know the anwser too.
(no subject)
Date: 2006-05-25 02:27 pm (UTC)(no subject)
Date: 2006-05-25 02:28 pm (UTC)(no subject)
Date: 2006-05-25 02:30 pm (UTC)(ps I got Nine Worlds and it seems to be like a mage campaign)
(no subject)
Date: 2006-05-25 02:43 pm (UTC)(no subject)
Date: 2006-05-25 02:43 pm (UTC)(no subject)
Date: 2006-05-25 02:33 pm (UTC)The lecturer has asked a question, they've provided an answer, and they've been told they are wrong.
We've carefully looked at their answer and declared
So we've sent the student back to slap the lecturer around with a wet herring.
(no subject)
Date: 2006-05-25 02:53 pm (UTC)OK, he was a robotics engineer with Siemens, but still...
(no subject)
Date: 2006-05-25 03:04 pm (UTC)(no subject)
Date: 2006-05-25 03:08 pm (UTC)That reminds me, I should hop down to the beer festival tomorrow evening, really.
(no subject)
Date: 2006-05-25 02:53 pm (UTC)The obvious answer is that Quantity is an attribute of the Item element, but ProductID isn't (renamed from ProductCode) and InvoiceID isn't (it's extract from the grand parent).
'/SalesInvoice/Items/Item' is clearly the access path to the elements you're interested in, in standard "tree-structure" (I suspect it's actually XPath). So "/" means the document root, and SalesInvoice must therefore be the containing element for the entire document. <hand waves> You know what I mean, and I don't have to explain it :)
(no subject)
Date: 2006-05-25 02:56 pm (UTC)http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_oa-oz_5c89.asp
If you feel geeky :)
recordset
Date: 2006-05-25 02:59 pm (UTC)But it's not impossible that the other attributes and the content will get automagically included too.
Re: recordset
Date: 2006-05-25 03:01 pm (UTC)(no subject)
Date: 2006-05-25 03:00 pm (UTC)And yes, you are broadly right. The thing about the '/SalesInvoice/Items/Item' is that you get one row for each of these it finds. This is the obvious way it would work (so you may have guessed this). THe thing is she described it as just being the base for where all your xpath worked from. So when I asked her what would happen if you based it on '/SalesInvoice' and referred to 'Items/Item/@ProductCode' she told me that it would produce multiple rows for that which is provenly not so.
Still, should get on with this lab really...
(no subject)
Date: 2006-05-25 03:16 pm (UTC)Out of curiousity, if you do base it on "/SalesInvoice", and ask for the ProductCode, what does happen (you mention "provenly", which suggests you've tried it).
Personally, I'd expect one of: the first ProductCode (12), the last ProducCode(2), the "aggregation" of the productCodes (so 12+41+2, which is either 55 or 12412, depending on whether they're treated as strings or numbers). Or, and the only one I'd think could be "correct" in a specification: an error.
(no subject)
Date: 2006-05-25 03:26 pm (UTC)I suspect if being evaluated in a context where it expects a single value (rather than a set) then the xpath just looks through, finds one and then stops. This may well be as per spec since it would be a sensible way to spec it from a certain point of view. I would expect intelligent tools to provide warnings at that point though.
(no subject)
Date: 2006-05-25 03:29 pm (UTC)There's a reason I don't go on training courses...
(no subject)
Date: 2006-05-26 01:10 am (UTC)Even from an SQL point of view. In some sense you're asking for one thing (a column in your results row, to be the value of an Items/Item/@ProductCode for the SalesInvoice) in a context where there might be more than one. So the equivalent of ROWCOUNT 1 isn't a stupid consequence. And hopefully the XML-reading stuff for SQL Server will ensure that things by default are ORDER BY their actual order in the document, since any other default would be a bit crazy, and "no default order" would be a pain in the ass to remember given that XML is intrinsically ordered...
I would expect intelligent tools to provide warnings at that point though.
That would be nice, since you can tell from the schema whether it's possible to have more than one Items/Item/@ProductCode (and, for that matter, whether it's possible to have less than one - does that give an empty result set (because there are 0 /SalesInvoices having the required great-grandchild), or an error (on grounds that the result row for the /SalesInvoice can't be generated?)). Nevertheless, I suspect I have a lower opinion of intelligent tools than you do.
(no subject)
Date: 2006-05-26 08:36 am (UTC)(no subject)
Date: 2006-05-25 02:55 pm (UTC)Root/Child/Child
The 1 is a byte argument as explained in the MSDN files:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_oa-oz_5c89.asp
(no subject)
Date: 2006-05-25 03:04 pm (UTC)(no subject)
Date: 2006-05-25 03:05 pm (UTC)And did you know that? You've obviously gone and looked up the reference but did you do that before or after deciding on the answer?
And can you tell me what the value 8 does in practice? The course material only discusses 0,1,2,3...
(no subject)
Date: 2006-05-25 03:14 pm (UTC)*shamed*
(no subject)
Date: 2006-05-25 03:20 pm (UTC)*shamed*
(no subject)
Date: 2006-05-25 03:21 pm (UTC)'../../@InvoiceID' is an xpath statment
as is @Product ID. In the XPath notation form it is how you access an argument from the XML row.
(no subject)
Date: 2006-05-25 08:49 pm (UTC)(no subject)
Date: 2006-05-25 10:35 pm (UTC)(no subject)
Date: 2006-05-26 12:48 am (UTC)[*] Indeed, it almost certainly is a database row which has been mangled into a slightly strange structure for the sake of generating an example which somewhat arbitrarily uses attributes, text nodes and child elements. In a relational database the table would probably have a foreign key containing the InvoiceID, three numeric columns and two text columns. Those would therefore both have names, instead of one of them being anonymous and hence, due to the "aaa"-style content, having no obvious semantics. Of course maybe it's essential that Items be able to specify multiple text nodes and nested child elements with extensibility through new elements and/or namespacing. But I seriously doubt it, given that it's a Mickey Mouse example from a textbook.
(no subject)
Date: 2006-05-26 08:33 am (UTC)And the fact it's a text book simple example isn't going to make an ideal example of data which could do with being modelled in XML rather than in a relational format.
(no subject)
Date: 2006-05-27 02:59 pm (UTC)But my general point is that the general purpose of XML is to represent abstract data entities, and as such, you can call an element a "row", "column", "fish", or almost anything, provided that the thing you're calling it is what it actually does represent.
(no subject)
Date: 2006-05-26 08:35 am (UTC)(no subject)
Date: 2006-05-26 10:20 am (UTC)On the other hand, I know nothing of XML, so a lot of that syntax was fairly meaningless to me ;)
Well, very meaningless, really.
Question then, without understanding aaaaanything of most of this:
I can understand that:
ProductCode
Quantity
UnitPrice
are all attributes of 'Item' (that's the same principle as HTML - open an angular bracket, specify your initial *thing*, then specify further properties by using Attribute="Value" as syntax)
However - is there a reason why ProductName wasn't also listed as another attribute of the Item?
Or was that just the way the example was put together, and not actually of any significance?
(no subject)
Date: 2006-05-26 10:22 am (UTC)(no subject)
Date: 2006-05-26 10:41 am (UTC)(no subject)
Date: 2006-05-26 10:39 am (UTC)Narrating this through then step by step in semi-layman's terms (mostly because I don't know the correct ones to use anything properly technical):
You are specifying the elements of an invoice, which is called SalesInvoice.
Each of these invoice elements is an Item, and has attributes ProductCode,
Quantity & UnitPrice (ignoring that ProductName bit for a moment). In terms of directory structure, these are located at /SalesInvoice/Items/Item (Query: That would seem to be effectively a table called 'Items', and entries within it each specified as a new Item?)
You are trying to get specific information from this set of info, via a SELECT query - which could be said to read as:
"Return everything from the invoice items, for the following fields: Invoice ID, ProductID, and Quantity."
Reading directly across any of those items and their attributes, the following is clear:
* You are not specifying the InvoiceID in each Item. There was no need to do so - they're all elements of the same invoice, and it would have been inefficient to repeat whxat you'd already stated when opening the specific invoice - so logicially, we need to return to the invoice itself to get this info:
InvoiceID int '../../@InvoiceID' - go up two levels of the directory structure. (I'll trust you on the int & the @, I don't understand the syntax to know that's required. Out of interest, would InvoiceID int '../../@.' have also worked, or does . have a different meaning here? )
* There's nothing called ProductID in the original set of attributes - there's been a change of name here, because we actually want ProductCode.
ProductID int '@ProductCode'
* Quantity is still Quantity, and is specified in each indidivual element. No need for further faffing:
Quantity int
(no subject)
Date: 2006-05-27 03:20 pm (UTC)Sensible reasons for doing this in real life could include:
1) ProductName may in future need to contain further structure (unlikely in this case, although could be another way of doing (3) below).
2) The ordering of the contents of Item are important (unlikely in this case).
3) You might want to specify more than one ProductName for each Item (not necessarily unlikely in this case). <ProductName>Bike</ProductName> <ProductName lang="en">Bike</ProductName> <ProductName lang="fr">Vélo</ProductName> might make a certain amount of sense, with the lang-not-specified one being the default. Of course, listing a squillion languages for each item in an invoice might not be such a great idea. But ignoring that for a moment, it's reasonable to think that you might someday want to switch the language an invoice is displayed in after it has been generated, but that the item numbers, prices etc are fixed at that point (in a catalogue you'd want to list multiple prices, but once it's invoiced the currency has probably been fixed).
There are probably people working on the academic theory of contriving examples of stock/purchase control systems...