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

Chr*_*ins 3 xml sql sql-server security sql-server-2005

我试图在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 
Run Code Online (Sandbox Code Playgroud)

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

关于如何让这个工作的任何想法?我想尝试使我的xpath查询从SQL注入安全.

Sau*_*tka 8

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