我正在尝试在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查询。
答案 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