|
|
Question : OpenXML and inserting multiple rows (in multiple tables) with identity
|
|
Hello Experts!
Here is my problem (i use examples!!!):
i have an quite simple XML file which looks like this:
--------------------------------
Test foo bar Yak 123 foobar next
--------------------------------
the number of article and/or keyword items may vary.
now i have two tables: One to store the "Articles":
Articles ------------ ident int IDENTITY(1,1), name varchar(10)
One to store the "Keywords":
Keywords ------------ ident, keyword varchar(10)
I can use the OpenXML function to populate the articles table, like this:
-------------------------------- insert into Articles select * from OpenXML(@hDoc, 'data/article') with ( name varchar(10) 'name' ) --------------------------------
there is no problem inl getting the both articles into the table:
ident name ---------------- 1 Test 2 Yak
But now i want to assign the keywords to the articles using the auto-generated identity number (column: ident)! Please note, that the name element is not always unique.
The keywords table should look like this:
ident keyword ---------------- 1 foo 1 bar 2 123 2 foobar 2 next
I am looking for any method to get those results WITHOUT using a cursor.
|
Answer : OpenXML and inserting multiple rows (in multiple tables) with identity
|
|
First of all thanks, It's the first time I use these meta tags Here's new code to addresse problem 1) --new view create view v_article_keywords as select 0 as id, name, keyword from articles a inner join keywords k on a.ident = k.ident
--new trigger create trigger tg_v_article_keywords on v_article_keywords instead of insert as declare c1 cursor for select distinct id, name from inserted declare @name varchar(10), @id int open C1 fetch c1 into @id, @name while @@fetch_status = 0 begin insert Articles(name) values(@name) insert Keywords(ident, keyword) select scope_identity(), keyword from inserted where id = @id fetch c1 into @id, @name end close c1 deallocate c1
--new insert-select statement declare @xml varchar(8000), @hdoc int set @xml = ' Test foo bar Yak 123 foobar next ' exec sp_xml_preparedocument @hdoc out, @xml insert v_article_keywords (id, name, keyword) select id, name, keyword from openxml(@hdoc,'/data/article/keywords/keyword',1) with (id int '@mp:parentid', name varchar(10) '../../name', keyword varchar(10) 'text()') exec sp_xml_removedocument @hdoc
As for problem 2), I try to never use cursors and most of the time they can be avoided. In this case I can't think of any way to get rid of the cursor (except another kind of loop that won't be better performancewise)
>>Are there any known disadvantages using the method above?<< It somehow hides the complexity in the trigger and I tend to think the performance should not be too bad, cause it keeps things simple both in the trigger and in the insert-select code.
I must admit it's somehow unusual ... in fact I have seldom seen cases where INSTEAD OF triggers were used with real added value. I hope the code above is a good exemple ...
Cheers
Hilaire
|
|
|
|
|