正则表达式提取sql语句的@参数名,顺便修正subsonic的一个bug

        subsonic的InlineQuery非常好用,用于执行参数的Sql语句,防止被注入,其运行机制类似我之前写的《借用.net framework的string.Fromat(...),实现一个执行参数化SQL的方法》,都是先提前sql语句中的参数名,再根据参数名和传入的值动态构造Command.

贴一个官方的使用InlineQuery的示例:

Northwind.ProductCollection products =
   
new  InlineQuery()
    .ExecuteAsCollection
< Northwind.ProductCollection >
    (
" SELECT productID from products WHERE productid=@productid " 1 );

 

 

        今天用InlineQuery执行带参数的SQl语句时候,发现subsonic分析sql参数的一个bug,跟踪进入subsonic的源代码,发现其解析sql语句的参数是这样解析的:

private static List<string> ParseParameters(string sql)
{
     List<string> result = new List<string>();
     Regex paramReg = new Regex(@"@\w*");
     MatchCollection matches = paramReg.Matches(String.Concat(sql, " "));
     foreach(Match m in matches)
          result.Add(m.Value);
     return result;
}
注意看第三行,Regex paramReg = new Regex(@"@\w*"),它的其他机制是用正则表达式分组匹配,例如有以下sql语句:
SELECT * FROM students WHERE fname=@name;
SELECT @@ROWCOUNT
提取的时候连@@ROWCOUNT这样的变量都会被提取出来,

显然这不是我们想要的,我们想要的结果是,只提取@name这个参数名,这显然是不能满足要求的,真则表达式@"@\w*"未免处理得太草率了,还好开源的东西有源码好修改,最好花了10分钟时间(真是惭愧啊,好久没有用这玩意了)写正则表达式:([^@@](?<p>@\w+))|(?<p>^@\w+)

最后修改的代码如下:

private static List<string> ParseParameters(string sql)
{
     List<string> result = new List<string>();
     //Regex paramReg = new Regex(@"@\w*");
     //2009-2-29 修正正则表达式匹配参数时,Sql中包括@@rowcount之类的变量的情况,不应该算作参数
     Regex paramReg = new Regex(@"[^@@](?<p>@\w+)");
     MatchCollection matches = paramReg.Matches(String.Concat(sql, " "));
     foreach(Match m in matches)
          result.Add(m.Groups["p"].Value);
     return result;
}
 
各位如果还有简单点的写法,请留言告知这下,谢谢。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值