Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here are a couple of solutions for you.</p> <p>Sample data:</p> <pre><code>declare @xml xml set @xml = '&lt;EventSpecificData&gt; &lt;Keyword&gt; &lt;Word&gt;myWord&lt;/Word&gt; &lt;Occurences&gt;1&lt;/Occurences&gt; &lt;Context&gt;context&lt;/Context&gt; &lt;/Keyword&gt; &lt;/EventSpecificData&gt;' </code></pre> <p>Get the first value from node named Word regardless of parents. Use <code>//</code> to do a deep search and use <code>local-name()</code> to match node name.</p> <pre><code>declare @Attribute varchar(max) set @Attribute = 'Word' select @xml.value('(//*[local-name() = sql:variable("@Attribute")])[1]', 'varchar(max)') </code></pre> <p>Provide parent node name and attribute in separate variables using <code>local-name()</code> in two levels.</p> <pre><code>declare @Node varchar(max) declare @Attribute varchar(max) set @Attribute = 'Word' set @Node = 'Keyword' select @xml.value('(/EventSpecificData /*[local-name() = sql:variable("@Node")] /*[local-name() = sql:variable("@Attribute")])[1]', 'varchar(max)') </code></pre> <p>Since the parameter to <code>nodes</code> have to be a string literal it invites to use dynamic sql to solve this. It could look something like this to make it work with your original variable content.</p> <pre><code>set @Attribute = 'Keyword/Word' declare @SQL nvarchar(max) set @SQL = 'select @xml.value(''(/EventSpecificData/'+@Attribute+')[1]'', ''varchar(max)'')' exec sp_executesql @SQL, N'@xml xml', @xml </code></pre> <p><strong>But</strong> you should be aware of that if you use this you are wide open to SQL Injection attacks. Some devious end-user might come up with a attribute string that looks like this:</p> <pre><code>set @Attribute = 'Keyword/Word)[1]'', ''varchar(max)'') select @@version --' </code></pre> <p>Executing the dynamic SQL with that will give you two result sets. The <code>select @@version</code> is just there to show some harmless code but it might be much worse stuff in there.</p> <p>You can use <code>quotename()</code> to prevent the SQL injection attack. It will at least prevent the attempt made by me.</p> <pre><code>set @Attribute = 'Keyword/Word' set @SQL = 'select @xml.value('+quotename('(/EventSpecificData/'+@Attribute+')[1]', '''')+', ''varchar(max)'')' exec sp_executesql @SQL, N'@xml xml', @xml </code></pre> <p>Is the last version using <code>quotename()</code>safe? Have a look at this article by Erland Sommarskog <a href="http://www.sommarskog.se/dynamic_sql.html">The Curse and Blessings of Dynamic SQL</a>.</p> <p>Quote:</p> <blockquote> <p>So with quotename() and quotestring(), do we have as good protection against SQL injection as we have with parameterised commands? Maybe. I don't know of any way to inject SQL that slips through quotename() or quotestring(). Nevertheless, you are interpolating user input into the SQL string, whereas with parameterised commands, you don't.</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload