|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Query: Using dynamic XQuery expressions (urgent)I am trying to use sql server variable in the xQuery expression, but it's not working. In my case name of the element is dynamic and is stored in the sql server variable. Please refer to following sample * this statement generates error "select @xml.value( @expr ,'varchar(500)')" It would be gr8 if somebody could tell me an approach to query dynamic expressions. Thanks Narendra declare @xml xml set @xml = '<ApplicationRequest> <DataObject> <City> <CityId>1</CityId> <Name>Pune</Name> </City> </DataObject> </ApplicationRequest>' declare @NodeToRead varchar(150) set @NodeToRead = 'City' declare @expr nvarchar(250) set @expr = '(/ApplicationRequest/DataObject/' + @NodeToRead + '/Name)[1]' select @xml.value( @expr ,'varchar(500)') Hello Narendra,
Remember that the XQuery expression itself must be a string literally. Now, yes, there are constructors, but those don't seem to work in the where predicate where we'd want them to do for this. Here's the closest I could come with quickly: declare @NodeToRead varchar(150) set @NodeToRead = 'City' declare @query nvarchar(max) set @query = ' declare @xml xml set @xml = ''<ApplicationRequest> <DataObject> <City> <CityId>1</CityId> <Name>Pune</Name> </City> </DataObject> </ApplicationRequest>'' select @xml.value(''(for $node in (/ApplicationRequest/DataObject/*) where (local-name($node) = "' + @NodeToRead + '") return ($node/Name))[1]'',''nvarchar(max)'')' exec sp_executesql @stmt=@query BLECH! This would be nicer if it worked... declare @NodeToRead varchar(150) set @NodeToRead = 'City' declare @xml xml set @xml = '<ApplicationRequest> <DataObject> <City> <CityId>1</CityId> <Name>Pune</Name> </City> </DataObject> </ApplicationRequest>' select @xml.value('(for $node in (/ApplicationRequest/DataObject/*) where (local-name($node) = "{sql:variable("@NodeToRead")}") return ($node/Name))[1]','nvarchar(max)') I've forwarded this up to MRys as a suggestion for the next release... Thank you, Kent Tegels DevelopMentor http://staff.develop.com/ktegels/ Hi Narenda and Kent
Cleaning up Kent's second solution, you can write: declare @NodeToRead varchar(150) set @NodeToRead = 'City' declare @xml xml set @xml = '<ApplicationRequest> <DataObject> <City> <CityId>1</CityId> <Name>Pune</Name> </City> </DataObject> </ApplicationRequest>' select @xml.value('(for $node in (/ApplicationRequest/DataObject/*) where (local-name($node) = sql:variable("@NodeToRead")) return ($node/Name))[1]','nvarchar(max)') or rewrite the query to the shorter XPath expression select @xml.value('(/ApplicationRequest/DataObject/*[local-name() = sql:variable("@NodeToRead")]/Name)[1]','nvarchar(max)') In general, we have seen use cases for parameterizing the query methods with a string value. However there are some security issues to consider. I would appreciate if you can send your feature request through the MSDN Feedback center or send a mail to sqlwish (at) microsoft (dot) com. That way, the powers that keep track of customer feedback will see this issue appear and other people can vote on it (in the feedback center). Best regards Michael Show quoteHide quote "Kent Tegels" <kteg***@develop.com> wrote in message news:b87ad74ed978c7ba3ca6cda530@news.microsoft.com... > Hello Narendra, > > Remember that the XQuery expression itself must be a string literally. > Now, yes, there are constructors, but those don't seem to work in the > where predicate where we'd want them to do for this. Here's the closest I > could come with quickly: > > declare @NodeToRead varchar(150) > set @NodeToRead = 'City' > declare @query nvarchar(max) > > set @query = ' > declare @xml xml > set @xml = ''<ApplicationRequest> > <DataObject> > <City> > <CityId>1</CityId> > <Name>Pune</Name> > </City> > </DataObject> > </ApplicationRequest>'' > select @xml.value(''(for $node in (/ApplicationRequest/DataObject/*) > where (local-name($node) = "' + @NodeToRead + '") > return ($node/Name))[1]'',''nvarchar(max)'')' > > exec sp_executesql @stmt=@query > > BLECH! > > This would be nicer if it worked... > > declare @NodeToRead varchar(150) > set @NodeToRead = 'City' > declare @xml xml > set @xml = '<ApplicationRequest> > <DataObject> > <City> > <CityId>1</CityId> > <Name>Pune</Name> > </City> > </DataObject> > </ApplicationRequest>' > select @xml.value('(for $node in (/ApplicationRequest/DataObject/*) > where (local-name($node) = "{sql:variable("@NodeToRead")}") > return ($node/Name))[1]','nvarchar(max)') > > I've forwarded this up to MRys as a suggestion for the next release... > > Thank you, > Kent Tegels > DevelopMentor > http://staff.develop.com/ktegels/ > > In general, when you do not know the complexity of the XQuery, you will need
to use sp_executesql. Note that you will have to mediate against SQL and XQuery injection attacks if you provide external access to the query parameterization in any case... Best regards Michael Show quoteHide quote "Michael Rys [MSFT]" <m***@online.microsoft.com> wrote in message news:uohwK$H7FHA.808@TK2MSFTNGP09.phx.gbl... > Hi Narenda and Kent > > Cleaning up Kent's second solution, you can write: > > declare @NodeToRead varchar(150) > > set @NodeToRead = 'City' > > declare @xml xml > > set @xml = '<ApplicationRequest> > > <DataObject> > > <City> > > <CityId>1</CityId> > > <Name>Pune</Name> > > </City> > > </DataObject> > > </ApplicationRequest>' > > select @xml.value('(for $node in (/ApplicationRequest/DataObject/*) > > where (local-name($node) = sql:variable("@NodeToRead")) > > return ($node/Name))[1]','nvarchar(max)') > > > > or rewrite the query to the shorter XPath expression > > select @xml.value('(/ApplicationRequest/DataObject/*[local-name() = > sql:variable("@NodeToRead")]/Name)[1]','nvarchar(max)') > > > > In general, we have seen use cases for parameterizing the query methods > with a string value. However there are some security issues to consider. > > I would appreciate if you can send your feature request through the MSDN > Feedback center or send a mail to sqlwish (at) microsoft (dot) com. That > way, the powers that keep track of customer feedback will see this issue > appear and other people can vote on it (in the feedback center). > > Best regards > > Michael > > "Kent Tegels" <kteg***@develop.com> wrote in message > news:b87ad74ed978c7ba3ca6cda530@news.microsoft.com... >> Hello Narendra, >> >> Remember that the XQuery expression itself must be a string literally. >> Now, yes, there are constructors, but those don't seem to work in the >> where predicate where we'd want them to do for this. Here's the closest I >> could come with quickly: >> >> declare @NodeToRead varchar(150) >> set @NodeToRead = 'City' >> declare @query nvarchar(max) >> >> set @query = ' >> declare @xml xml >> set @xml = ''<ApplicationRequest> >> <DataObject> >> <City> >> <CityId>1</CityId> >> <Name>Pune</Name> >> </City> >> </DataObject> >> </ApplicationRequest>'' >> select @xml.value(''(for $node in (/ApplicationRequest/DataObject/*) >> where (local-name($node) = "' + @NodeToRead + '") >> return ($node/Name))[1]'',''nvarchar(max)'')' >> >> exec sp_executesql @stmt=@query >> >> BLECH! >> >> This would be nicer if it worked... >> >> declare @NodeToRead varchar(150) >> set @NodeToRead = 'City' >> declare @xml xml >> set @xml = '<ApplicationRequest> >> <DataObject> >> <City> >> <CityId>1</CityId> >> <Name>Pune</Name> >> </City> >> </DataObject> >> </ApplicationRequest>' >> select @xml.value('(for $node in (/ApplicationRequest/DataObject/*) >> where (local-name($node) = "{sql:variable("@NodeToRead")}") >> return ($node/Name))[1]','nvarchar(max)') >> >> I've forwarded this up to MRys as a suggestion for the next release... >> >> Thank you, >> Kent Tegels >> DevelopMentor >> http://staff.develop.com/ktegels/ >> >> > > Hello Michael Rys [MSFT],
ARRRGH! I think I tried every variation of this EXCEPT for just assuming that sql:variable didn't need to be in a constructor at all. Thanks! Kent Hi Eugene,Michael,Kent
Thanks a lot for ur solutions. Both solutions are working (With loop & without loop). I could read values of dynamic node. You guys were really a good help Thanks & Regards Narendra Chaudhari *** Sent via Developersdex http://www.developersdex.com *** Here's a couple of examples on how to achieve this:
select @xml.value(' (/ApplicationRequest/DataObject/*[local-name() = sql:variable("@NodeToRead")]/Name)[1] ','nvarchar(500)') select @xml.query(' /ApplicationRequest//*[local-name() = sql:variable("@NodeToRead")]/Name ') Best regards, Eugene --- This posting is provided "AS IS" with no warranties, and confers no rights. Show quoteHide quote "Narendra" <narendr***@gmail.com> wrote in message news:1132312867.852168.258060@f14g2000cwb.googlegroups.com... > hi Guys, > > I am trying to use sql server variable in the xQuery expression, but > it's not working. > In my case name of the element is dynamic and is stored in the sql > server variable. > > Please refer to following sample > * this statement generates error "select @xml.value( @expr > ,'varchar(500)')" > > It would be gr8 if somebody could tell me an approach to query dynamic > expressions. > > Thanks > Narendra > > declare @xml xml > set @xml = '<ApplicationRequest> > <DataObject> > <City> > <CityId>1</CityId> > <Name>Pune</Name> > </City> > </DataObject> > </ApplicationRequest>' > > declare @NodeToRead varchar(150) > > set @NodeToRead = 'City' > > > declare @expr nvarchar(250) > set @expr = '(/ApplicationRequest/DataObject/' + @NodeToRead + > '/Name)[1]' > > select @xml.value( @expr ,'varchar(500)') >
Other interesting topics
Getting Empty Tags Returned From The Server
Return Value from SQLXMLBULKLOADLib.SQLXMLBulkLoad3Class.Execute Confirm methodology or advise how to generate performance reports for eCommerce facility. xml-dml insert element with an attribute containig sql:variable dynamic XML using for XML explicit Add perent element trouble with annotated xsd mapping schemas sending xml data from stored procedure Tree structure data in xml .. Query Notification |
|||||||||||||||||||||||