.NET Framework 2.0 中,Microsoft 在 System.Data.Common 名称空间下定义了一组类用来让程序员编写适用于不同数据库的数据访问代码,而且还在 Enterprise Library 中提供了一个标准的示范。但是这里面有很大的一个问题就是当程序员使用带参sql的方式来访问数据库时,一切都变得毫无意义了。因为 SQL Server 支持以 @ 为前缀的名称参数、Oracle 则支持以 : 为前缀的名称参数,而当使用 OleDb 访问 Access 时就变成了使用 ? 作为占位符的位置参数语法。在编写程序时,必须针对不同的 ADO.NET Provider 编写 sql 语句。

本文将介绍一种方法,可以使得 SQL Server、Oracle 也支持以 ? 为占位符的位置参数语法。要想实现这个效果,就需要将 sql 语句中的 ? 占位符替换成相应的名称参数。下面以 SQL Server 数据库为例,假如有一条 sql 语句:

select count(0) from sys_user where user_code=? and password=?

如果能够将其转变为:

select count(0) from sys_user where user_code=@p1 and password=@p2

就可以使 SQL Server 也支持以 ? 为占位符的位置参数了。

在做这个变换时,我使用了一个正则表达式。通过这个正则表达式,可以将 sql 语句中的所有 ? 占位符找到,并将其替换为以 @ 为前缀的位置参数,代码如下:

private string PreparePlaceHolder(string srcSql)
{
string _sqlTokenPattern = "[\\s]+|(?<string>'([^']|'')*')|(?<comment>(/\\*([^\\*]|\\*[^/])*\\*/)|(--.*))|(?<parametermarker>\\?)|(?<query>select)|(?<identifier>([\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}\\p{Nd}\\uff3f_#$]+)|(\"([^\"]|\"\")*\"))|(?<other>.)";
Regex sqlTokenParser = new Regex(_sqlTokenPattern, RegexOptions.ExplicitCapture); List<Group> groups = new List<Group>();
bool flag = false; for (Match match = sqlTokenParser.Match(srcSql); Match.Empty != match; match = match.NextMatch())
{
if (!match.Groups["comment"].Success)
{
if ((match.Groups["comment"].Success || match.Groups["string"].Success) || match.Groups["other"].Success)
{
flag = true;
}
else if (match.Groups["query"].Success)
{
if (!flag)
{
// 走到这里,表示这是一条 select 语句。
}
}
else if (match.Groups["parametermarker"].Success)
{
// 走到这里,表示发现了一个 ? 占位符。
groups.Add(match.Groups["parametermarker"]);
}
}
} StringBuilder desSql = new StringBuilder(srcSql); for (int i = groups.Count - ; i >= ; i--)
{
Group group = groups[i]; desSql.Remove(group.Index, group.Length);
desSql.Insert(group.Index, ParameterToken + "p" + (i + ));
}
return desSql.ToString();
}

利用上述方法,可以编写出更加通用的 SQLHelper 类。程序员可以在任何时候使用位置参数语法来执行 sql 语句,而不必考虑对应的 ADO.NET Provider 是否支持位置参数。

通过一个正则表达式,让SQL Server数据库的带参sql也支持位置参数语法!的更多相关文章

  1. SQL Server数据库性能优化之SQL语句篇【转】

    SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...

  2. 转载——SQL Server数据库性能优化之SQL语句篇

    转载自:http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 1. 按需索取字段,跟“SELECT *”说拜拜 字段的提取一 ...

  3. SQL SERVER数据库性能优化之SQL语句篇

    (引用自重明鸟的博客,方便学习和查看) 1. 按需索取字段,跟“SELECT *”说拜拜 字段的提取一定要按照“用多少提多少”的原则,避免使用“SELECT *”这样的操作.做了这样一个实验,表tbl ...

  4. Sql server 数据库中,纯SQL语句查询、执行 单引号问题。

    在默认值情况下, select 'abc',Titile from tb_Name;  ---输出内容 是abc: 如果想输出 单引号 'abc,需要使用select '''abc',Titile f ...

  5. SQL Server 数据库备份还原常用SQL语句及注意

    1.备份数据库 backup database db_name to disk='d:\db_name.bak' with format --通过使用with format可以做到覆盖任何现有的备份和 ...

  6. delphi连接sql server数据库,并根据sql语句查询出数据显示--初级

    需要用到四个组件,分别为: 1.ADOConnection1 设置Connectionstring属性(连接串),loginPrompt属性控制是否连接记住了密码: 2.ADOQuery1 设置Con ...

  7. 【转】PowerShell 连接SQL Server 数据库 - ADO.NET

    转至:http://www.pstips.net/connect-sql-database.html PowerShell 通过ADO.NET连接SQL Server数据库,并执行SQL脚本.工作中整 ...

  8. 5、SQL Server数据库、T-SQL

    SQL Server数据库基础 一.安装SQL Server数据库 setup.exe->安装->全新SQL Server独立安装或向现有安装添加功能->输入序列号->下一步- ...

  9. SQL Server学习之路(七):Python3操作SQL Server数据库

    0.目录 1.前言 2.准备工作 3.简单测试语句 4.提交与回滚 5.封装成类的写法 1.前言 前面学完了SQL Server的基本语法,接下来学习如何在程序中使用sql,毕竟不能在程序中使用的话, ...

随机推荐

  1. [AS3]as3与JS的交互(AS3调用JS)实例说明

    一,AS3 vs JavaScript (1)AS3调用JS 函数: ExternalInterface.(functionName:, arguments): //AS3 Code 属性: 同上,通 ...

  2. 解决jQuery.live在mobile safari(iphone / ipad / ipod)绑定失败的问题

    解决方案: 给要使用live绑定事件的元素,添加“cursor:pointer”样式即可! 如: a,input,td{cursor:pointer;}

  3. inline函数

    C语言中的inline函数并不是单纯的用函数块内容来替换,也可能存在局部变量啥的.另外,使用inline定义的函数只是建议编译器作为内联函数处理,但并不一定真会这样处理.inline一般直接在头文件中 ...

  4. asp.net生成缩略图、文字图片水印

    /// <summary> /// 会产生graphics异常的PixelFormat /// </summary> private static PixelFormat[] ...

  5. SQL常用日期函数

    原文:http://www.cnblogs.com/coconut_zhang/archive/2009/02/02/1382598.html 1. 当前系统日期.时间 select getdate( ...

  6. iOS 类管理

    CocoaPods安装和使用教程 Code4App 原创文章.转载请注明出处:http://code4app.com/article/cocoapods-install-usage 目录 CocoaP ...

  7. hdu1251统计难题

    Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己 ...

  8. [Linked List]Sort List

    otal Accepted: 59473 Total Submissions: 253637 Difficulty: Medium Sort a linked list in O(n log n) t ...

  9. PCL点云库增加自定义数据类型

    #include <pcl/filters/passthrough.h> #include <pcl/filters/impl/passthrough.hpp> // the ...

  10. html中的圆角边框

    border-radius:20px; radius:以某某为半径画圆. 如何制作一个圆形: div{height:150px;//像素的一半,再加上边框的像素 width:150px; border ...