Archive for the ‘SQL Server’ category

STUFF & FOR XML PATH

March 2nd, 2009

On the get the job done front, my client had a question today that, while it makes me cringe a little to answer the way I did, it got him moving again.

[Thanks to Mike Levy for pointing me in the right direction]

My client has a small administrative utility that displays Things.  Things can be applied to 0 or more categories.  Looks kinda’ like this:

image

He’s using a 3rd party control for the grid itself which provides really easy filtering, but it wouldn’t work with the data structures to which he had been binding.  So he wanted to know how he could return the category listing as a delimited string directly from the T-SQL.

Here’s the gist of his schema (nothing fancy):

Schema

 

How we solved it:

SELECT Id, Name, STUFF(
            (SELECT cat.Name + ‘; ‘ AS [text()]
            FROM Category AS cat
            INNER JOIN ItemCategories AS ic ON cat.Id = ic.CategoryId
            WHERE (ic.ItemId = Item.Id) FOR XML PATH(”)
            ), 1, 0, ”
              )
FROM Item

Obviously we would like to move the UI junk out of the DB, but he can deal with that when he understands the 3rd party control a little better.  Right now, he’s giving his customers some more features.

SQL Server 2000 vs 2005 Lazy XML Validation

August 19th, 2008

Someone was looking to do quick-and-dirty validation of an Xml document inside a SQL Server procedure today.  I assumed, and regretted, that he meant 2005, which would have looked like this:

declare @xml1 xml 
declare @xml2 xml 
set @xml1 = ‘<Node1><Node2 attrib=”This is it.” /></Node1>’
set @xml2 = ‘<Node1><Node2 /></Node1>’
select Col.value(’count(./@attrib)’, ‘int’) as count
from @xml1.nodes(’Node1/Node2′) as Tbl(Col)

select Col.value(’count(./@attrib)’, ‘int’) as count
from @xml2.nodes(’Node1/Node2′) as Tbl(Col)

After being told, “that blows up”, I jogged the memory a bit and came up with this mess:

/* THE STUPID WAY */
DECLARE @hdoc int
DECLARE @doc1 varchar(MAX)
DECLARE @doc2 varchar(MAX)
set @doc1 = ‘<Node1><Node2 attrib=”This is it.” /></Node1>’
set @doc2 = ‘<Node1><Node2 /></Node1>’
/* DOC 1 */
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc1

IF EXISTS( SELECT    *
FROM       OPENXML (@hdoc, ‘/Node1/Node2/@attrib’,1)
            WITH (attrib  varchar(20)))
BEGIN
PRINT ‘Dumb ass’
END
exec sp_xml_removedocument @hdoc

/* DOC 2 */
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc2

IF EXISTS( SELECT    *
FROM       OPENXML (@hdoc, ‘/Node1/Node2/@attrib’,1)
            WITH (attrib  varchar(20)))
BEGIN
PRINT ‘Dumb ass’
END
exec sp_xml_removedocument @hdoc

 

Moral of the store?  UPGRADE!