如何在SQL Server中创建参数化XPath查询?

时间:2009-07-16 14:14:29

标签: sql sql-server xml sql-server-2005 security

我正在尝试在SQL服务器中编写一个参数化查询,该参数使用参数值作为XPath的一部分,但它似乎不像我期望的那样工作。这是我的样本:

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 

此代码导致错误: xml数据类型方法“value”的参数1必须是字符串文字。

关于如何让它发挥作用的任何想法?我想尝试从SQL注入中保护我的xpath查询。

2 个答案:

答案 0 :(得分:8)

您应该使用sql:variable("@LanguagePath1")而不仅仅是@LanguagePath1。阅读更多相关信息here。虽然我不确定动态xpath是否可行:)但xmltest.value('(/languages/language[@id=sql:variable("@languageCode")])[1]之类的东西应该有用。

答案 1 :(得分:0)

如果要动态地给出整个条件,该怎么办?

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

select *  from ##example 
where @clause