2009-07-16 6 views
3

Ich versuche, eine parametrisierte Abfrage in SQL Server schreiben, die einen Parameterwert als Teil des XPath verwendet, aber es scheint nicht so zu funktionieren, wie ich es erwarten würde. Hier ist mein Beispiel:Wie erstelle ich parametrisierte XPath-Abfragen in SQL Server?

create table ##example (xmltest xml) 

declare @LanguagePath varchar(75) 

set @LanguagePath = '(/languages/language[@id="en-US"])[1]' 
insert into ##example 
values ('<languages> 
      <language id="en-US">c</language> 
      <language id="es-ES">c</language> 
     </languages>') 

insert into ##example 
values ('<languages> 
      <language id="en-US">b</language> 
      <language id="es-ES">b</language> 
     </languages>') 


insert into ##example 
values ('<languages> 
      <language id="en-US">a</language> 
      <language id="es-ES">a</language> 
     </languages>') 

--This is a working statement: 
--select * from ##example 
--order by xmltest.value('(/languages/language[@id="en-US"])[1]', 'varchar') 


declare @SQL nvarchar(4000) 
set @SQL = ' 
select * from ##example 
order by xmltest.value(@LanguagePath1, ''varchar'') 
' 

exec sp_executesql @SQL, N'@LanguagePath1 varchar(75)', @LanguagePath1 = @LanguagePath; 

drop table ##example 

Dieser Code führt zu dem Fehler: Das Argument 1 der XML-Datentyp-Methode „Wert“ muss ein Zeichenfolgenliteral sein.

Irgendwelche Ideen, wie ich das zum Laufen bringen kann? Ich würde gerne versuchen, meine XPath-Abfrage vor SQL-Injection zu schützen.

Antwort

8

Sie sollten sql:variable("@LanguagePath1") anstatt nur @LanguagePath1 verwenden. Lesen Sie mehr darüber here. Obwohl ich nicht sicher bin, ob dynamischer xpath funktioniert :) Jedoch sollte so etwas wie xmltest.value('(/languages/language[@id=sql:variable("@languageCode")])[1] funktionieren.

+0

Süße danke. Genau das habe ich gesucht. –

+0

Saulius, warum funktioniert Ihre Lösung, aber nicht in meinem Fall? siehe: http://goo.gl/pI4Ap – ekkis

0

Was ist, wenn die ganze wo Bedingung dynamisch angegeben werden soll.

@clause = xmltest.value('(/languages/language[@id="en-US"])[1]', 'varchar')=1 

select * from ##example 
where @clause 
+1

Ich glaube nicht, dass das funktionieren würde, weil Sie eine Where-Klausel als Parameter übergeben können. Sie könnten das Ganze in eine Zeichenkette verwandeln und die @klause damit verketten und das würde funktionieren, aber das wäre dann nicht wirklich eine parametrisierte Abfrage, die nichts anderes wäre, als die ganze Zeichenkette einzugeben, so dass Sie die Sicherheit der Parameter beim Versuch, SQL-Injektion zu vermeiden. Wie es Saulius gemacht hat, funktioniert es gut. –

Verwandte Themen