Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.databases.ms-sqlserver > #962 > unrolled thread

Help for XML data type in ms-sqlserver

Started byEnder Karadağ <enkaradag@gmail.com>
First post2012-04-09 10:35 -0700
Last post2012-04-19 10:51 -0700
Articles 9 — 2 participants

Back to article view | Back to comp.databases.ms-sqlserver


Contents

  Help for XML data type in ms-sqlserver Ender Karadağ <enkaradag@gmail.com> - 2012-04-09 10:35 -0700
    Re: Help for XML data type in ms-sqlserver Erland Sommarskog <esquel@sommarskog.se> - 2012-04-09 21:22 +0200
      Re: Help for XML data type in ms-sqlserver Ender Karadağ <enkaradag@gmail.com> - 2012-04-09 13:32 -0700
        Re: Help for XML data type in ms-sqlserver Erland Sommarskog <esquel@sommarskog.se> - 2012-04-09 23:31 +0200
          Re: Help for XML data type in ms-sqlserver Ender Karadağ <enkaradag@gmail.com> - 2012-04-09 14:59 -0700
            Re: Help for XML data type in ms-sqlserver Erland Sommarskog <esquel@sommarskog.se> - 2012-04-10 22:14 +0200
              Re: Help for XML data type in ms-sqlserver Ender Karadağ <enkaradag@gmail.com> - 2012-04-10 15:40 -0700
                Re: Help for XML data type in ms-sqlserver Erland Sommarskog <esquel@sommarskog.se> - 2012-04-11 07:34 +0000
                  Re: Help for XML data type in ms-sqlserver Ender Karadağ <enkaradag@gmail.com> - 2012-04-19 10:51 -0700

#962 — Help for XML data type in ms-sqlserver

FromEnder Karadağ <enkaradag@gmail.com>
Date2012-04-09 10:35 -0700
SubjectHelp for XML data type in ms-sqlserver
Message-ID<19738bce-58dd-477f-a1f2-a87edd2064b7@p6g2000yqi.googlegroups.com>
Hi guys,

ive searched net but could not find a suitable technique

assume i have two tables;

table : invoice
ID bigint identity
DOCNUMBER nvarchar(30)
DATE datetime

table : invoicedetails
ID bigint identity
PRODUCTID bigint (assume we have a product table, and this field is FK
to product.ID
AMOUNT numeric(18,3)
PRICE numeric (18,2)
INVOICEID bigint (FK to invoice.ID)

i am trying to save an invoice (lets say DOCNUMBER: A001, date :
04.09.2012 with two lines PRODUCTID=1, AMOUNT=10, PRICE=5.25,
PRODUCTID=2, AMOUNT=5, PRICE=4.75)

the common technique is inserting into invoice table first, getting
the identity ID value for master record, and saving lines with this
INVOICEID in a loop.

now i want to design a sqlserver stored procedure with an xml
parameter, and returning identity ID value in invoice table.

my xml should look like that;

<ROOT>
  <INVOICE>
    <DOCNUMBER>A001</DOCNUMBER>
    <DATE>04.09.2012</DATE>
      <LINES>
        <LINE>
          <PRODUCTID>1</PRODUCTID>
          <AMOUNT>10</AMOUNT>
          <PRICE>5.25</AMOUNT>
        </LINE>
        <LINE>
          <PRODUCTID>1</PRODUCTID>
          <AMOUNT>10</AMOUNT>
          <PRICE>5.25</AMOUNT>
        </LINE>
      </LINES>
  </INVOICE>
</ROOT>

with one shot, i want to save this schema into database.

dbo.proc_saveinvoice(xmlinvoice:xml)

any idea?

Thanks for all;)

[toc] | [next] | [standalone]


#963

FromErland Sommarskog <esquel@sommarskog.se>
Date2012-04-09 21:22 +0200
Message-ID<XnsA030D96067AF5Yazorman@127.0.0.1>
In reply to#962
Ender Karada? (enkaradag@gmail.com) writes:
> the common technique is inserting into invoice table first, getting
> the identity ID value for master record, and saving lines with this
> INVOICEID in a loop.

Nah. I would say "was". No one does that any more. Or at least no one 
should.
 
> now i want to design a sqlserver stored procedure with an xml
> parameter, and returning identity ID value in invoice table.

So that is the way to go. Or a table-valued parameter if you are on 
SQL 2008 or later.
 
> my xml should look like that;
> 
><ROOT>
>  <INVOICE>
>     <DOCNUMBER>A001</DOCNUMBER>
>     <DATE>04.09.2012</DATE>
>       <LINES>
>         <LINE>
>           <PRODUCTID>1</PRODUCTID>
>           <AMOUNT>10</AMOUNT>
>           <PRICE>5.25</AMOUNT>
>         </LINE>
>         <LINE>
>           <PRODUCTID>1</PRODUCTID>
>           <AMOUNT>10</AMOUNT>
>           <PRICE>5.25</AMOUNT>
>         </LINE>
>       </LINES>
>  </INVOICE>
></ROOT>
> 
> with one shot, i want to save this schema into database.

Since you say "should", I assume that you have control over the design 
of the document. Attribute-centric XML is easier to deal with:

<ROOT>
  <INVOICE DOCNUMBER="A001" DATE="04.09.2012"
     <LINE PRODUCTID="1" AMOUNT="10" PRICE="5.25" />
     <LINE PRODUCTID="1" AMOUNT="10" PRICE="5.25" />
  </INVOICE>
</ROOT>

I also removed the <LINES> tag, because it serves no purpose.

To insert into the tables do:

DECLARE @t TABLE (ident     int NOT NULL PRIMARY KEY,
                  docnumber nvarchar(30) UNIQUE)

INSERT invoice(docnumber, date)
   OUTPUT inserted.id, inserted.docnumber INTO @t
   SELECT Docnumber = T.c.value('@DOCNUMBER', 'nvarchar(30)'),
          Date      = T.c.value('@DATE', 'datetime')
   FROM   @xml.nodes('/ROOT/INVOICE') AS T(c)

INSERT invoicedetails (invoiceid, product_id, amount, price)
   SELECT t.id, 
          line.c.value('@PRODUCTID', 'int),
          line.c.value('@AMOUT', 'numeric(18,3)'),
          line.c.value('@PRICE', 'numeric(18,2)')
   FROM   @xml.nodes('/ROOT/INVOICE') AS T(c)
   JOIN   @t t ON t.docunumber = T.c.value('@DOCNUMBER', 'nvarchar(30)')
   CROSS  APPLY T.c.nodes('LINE') AS line(c)


By the way, I get an uneasy feeling when I see your table definition of 
invoicedetails and the sample data. What does it mean that two identical 
rows are inserted? Shouldn't (invoiceid, productid) be the primary key?

-- 
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx

[toc] | [prev] | [next] | [standalone]


#964

FromEnder Karadağ <enkaradag@gmail.com>
Date2012-04-09 13:32 -0700
Message-ID<08cbb43e-4193-4305-b6b2-a1a1320ab65b@w17g2000yqe.googlegroups.com>
In reply to#963
thanks for your explanatory reply

first of all
> By the way, I get an uneasy feeling when I see your table definition of
> invoicedetails and the sample data. What does it mean that two identical
> rows are inserted? Shouldn't (invoiceid, productid) be the primary key?

sorry, in my sample xml i had repeated first line by mistake. the
second line there should look like PRODUCTID="2" AMOUNT="5"
PRICE="4.75"

actually ive already done something like that before ive written that
post. (using OPENXML)

two things here disturbing me;

1) .... where/on xxx.DOCUMENTNO=yyy.DOCUMENTNO disturbs me /i dont
know why/

2) my actual purpose here is; what if our xml contains more than one
invoice data?
such as
<ROOT>
<INVOICE>
..nodes for 1st invoice..
</INVOICE>
<INVOICE>
..nodes for 2nd one
</INVOICE>
</ROOT>

or much more complex; what if our xml contains more than one types of
document (such as invoice and purchase details etc)
<ROOT>
<INVOICE>
..nodes for an invoice..
</INVOICE>
<PURCHASE>
..nodes for a purchase document, not related with the previous
invoice..
</INVOICE>
<PURCHASE>
..nodes for an other purchase document..
</PURCHASE>
</INVOICE>
..nodes for a second invoice..
<INVOICE>

etc.

im new to use xml as a datatype in mssql. perhaps im expecting much
from this technique.

thanks again, ur code seems better for a single document

[toc] | [prev] | [next] | [standalone]


#965

FromErland Sommarskog <esquel@sommarskog.se>
Date2012-04-09 23:31 +0200
Message-ID<XnsA030EF44F38ADYazorman@127.0.0.1>
In reply to#964
Ender Karada? (enkaradag@gmail.com) writes:
> actually ive already done something like that before ive written that
> post. (using OPENXML)

OPENXML is legacy, although it has to be admitted that it sometimes 
performs better than the newer xml type methods. But since the type methods 
does not require the call to sp_xml_prepare/removedocument, I prefer
them over OPENXML.
 
> 1) .... where/on xxx.DOCUMENTNO=yyy.DOCUMENTNO disturbs me /i dont
> know why/
> 
> 2) my actual purpose here is; what if our xml contains more than one
> invoice data?

Guess what? My solution is aimed to handle that situation. And that's 
why get this join that disturbs you. Try it!

-- 
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx

[toc] | [prev] | [next] | [standalone]


#966

FromEnder Karadağ <enkaradag@gmail.com>
Date2012-04-09 14:59 -0700
Message-ID<cbeb22d5-cb98-4afb-b249-acfa455e2997@m13g2000yqi.googlegroups.com>
In reply to#965
thanks again,

dont get that "disturbing" on ur solution. i mean ive also used
xxx.DOCUMENTNO=yyy.DOCUMENTNO with my code of OPENXML. and my code
looks disturbing.
document number may not be a unique value (some documents may even
have a null document number) thats why its disturbing me. actually,
this join works for only "inserted" table, so no problem. but that
still makes me disturbing.

also, if i can decide a teqnique for this situation, i may use same
technique in all these master-detail structures. in our project, some
of this kind of master detail structures may have no row for that kind
of join.

/by the way, im not good at english, perhaps im chosing the wrong word
for "disturbing"/

what would ur solution be for a "one shot" insert for more than one
invoice?

what about that?
1) insert multiple rows in invoice table
2) create a temp table for inserted invoice ID values /these ID
numbers have to be kept somewhere/
3) fill the temp table with the inserted rows ID values
4) insert multiple rows in invoicedetail table (with a join btw XML
and #table)

im not sure how to implement that and wats the most efficient solution

how would u design that?

thanks

[toc] | [prev] | [next] | [standalone]


#968

FromErland Sommarskog <esquel@sommarskog.se>
Date2012-04-10 22:14 +0200
Message-ID<XnsA031E234E604Yazorman@127.0.0.1>
In reply to#966
Ender Karada? (enkaradag@gmail.com) writes:
> dont get that "disturbing" on ur solution. i mean ive also used
> xxx.DOCUMENTNO=yyy.DOCUMENTNO with my code of OPENXML. and my code
> looks disturbing.
> document number may not be a unique value (some documents may even
> have a null document number) thats why its disturbing me. actually,
> this join works for only "inserted" table, so no problem. but that
> still makes me disturbing.

You did not say anything, so I had to make a guess. I find it somewhat
problematic - or disturbing :-) that there is no unique in the incoming 
data. How do you protect yourself against duplicates? Or do you trust the 
source?

If there is nothing that uniquely identifies each invoice in the data, this 
makes about impossible to shred the document in the way I suggested. Maybe 
it's possible if you use FLOWR operators in XQuery, but I am not going to 
try that now.

Then again, what version of SQL Server are you using? Does it have to be 
XML?
 
> /by the way, im not good at english, perhaps im chosing the wrong word
> for "disturbing"/

I took "disturbing" to mean that you did not like it for esthetic
reasons.
 

-- 
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx

[toc] | [prev] | [next] | [standalone]


#969

FromEnder Karadağ <enkaradag@gmail.com>
Date2012-04-10 15:40 -0700
Message-ID<d8c72fb8-60ce-4499-aa1a-019595d41b6f@d4g2000vbn.googlegroups.com>
In reply to#968
thanks for not getting that "disturbing" thing wrong;)

while talking about an invoice, of course we will have some unique
values in the master row. /but document number of an invoice may be a
null or a zero length string also/ but im trying to use this technique
for all master detail record sets. for instance, while saving a "group
list" /we have a just group name for master row, and have some group
details. some distinct groups may have the same group name/ and i have
more than 50 master detail schemas. so this technique may not fail for
dublicate records/
i wrote about a 2 levels document in order to make it simple, but for
instance my real invoice document has 4 levels /invoice master,
invoice rows, invoice row details product list (there may be more than
1 product for an invoice row), invoice rows product list discount
details (there may be unlimited number of discounts for each product
in each rows) etc./

but if i can find a perfect method for 2 levels, developing wont be
problem i think.

to admit, up to now, i was trusting the application code to prevent
invalid data. but now my goal is doing this with sqlserver functions
and removing all the validity controls from the application.

/last week, one of our programmers designed a plugin for our system.
there was a bug and that plugin wrote some invalid rows into orders
and ordersdetails table. thats why i want to move all the saving
procedures into sqlserver/ /after solving this i may also prevent
sqlserver sessions from accepting "INSERT INTO" and "UPDATE"
statements, just accepting "SAVE_XXX_DOCUMENT" functions i decide
here/

we use sqlserver2005 (and 2008 somewhere) now. but may upgrade all db
servers to 2008R2

actually im not locked to xml type for this job. what would your
advice be here? in terms of ease of implementation or working
performance etc.

thank you, regards

[toc] | [prev] | [next] | [standalone]


#970

FromErland Sommarskog <esquel@sommarskog.se>
Date2012-04-11 07:34 +0000
Message-ID<XnsA0326161F8400Yazorman@127.0.0.1>
In reply to#969
Ender Karada? (enkaradag@gmail.com) writes:
> we use sqlserver2005 (and 2008 somewhere) now. but may upgrade all db
> servers to 2008R2
> 
> actually im not locked to xml type for this job. what would your
> advice be here? in terms of ease of implementation or working
> performance etc.


Throw SQL 2005 the window and aim at SQL 2008 or SQL 2012. There are a 
couple of new features will help you.

If you use XML, and the XML has enough data to identify each master unique, 
but you don't insert all these fields in the table, you still have a problem 
with mapping the identity values, because you can only list columns you 
inserted in the OUTPUT clause. On SQL 2008 this can be mitigated by using 
the MERGE statement.

Then again, SQL 2008 introduces another features which saves from XML 
altogether: table-valued parameters.

In this context, it is also worth mentioning that SQL 2012 introduces 
sequences, which is a better alternative for surrogate keys over identity 
columns.


-- 
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

[toc] | [prev] | [next] | [standalone]


#992

FromEnder Karadağ <enkaradag@gmail.com>
Date2012-04-19 10:51 -0700
Message-ID<edd5d749-376b-44f3-8d49-16a3bb41082a@d4g2000vbn.googlegroups.com>
In reply to#970
Hi again.

im working on the xml subject for a week. ive solved all i think.

thank u for the advices, they worked a lot for me. ive done lots of
work with xml datatypes (and ive got surprised, xml is working faster
than ive expected, also indexes on xmls are working good)

i would be happy if u have a comment about that subject also:

http://groups.google.com/group/comp.databases.ms-sqlserver/browse_thread/thread/163c4a8e49bb2d37?hl=tr#

[toc] | [prev] | [standalone]


Back to top | Article view | comp.databases.ms-sqlserver


csiph-web