.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. wxpython 拖放

    拖放对用户是非常直观.它在许多桌面应用程序,用户可以复制或只需用鼠标拖动和删除另一个窗口中移动对象从一个窗口到另一个中. 拖放操作包括以下步骤 - 声明拖放目标 创建数据对象 创建 wx.DropSo ...

  2. lua的学习

    lua是什么 Lua是一中嵌入式的脚本语言. Lua语言可以独立进行编程,但这不是其主要的使用方式.Lua虽然有动态.灵活的语法提供强大的功能,但并不像 Java.Python 等一样有一个完善的库( ...

  3. 【floyd存字典序路径】【HDU1385】【Minimum Transport Cost】

    题目大意 求多组i到j的最短路径 并输出字典序最小.... 现在只会floyd的方式 利用dis[i][j] 表示i到j的路径中i 后面的节点 更新是比较dis[i][j] dis[i][k]. 记住 ...

  4. 使用FileSystemWatcher捕获系统文件状态

    源代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...

  5. maven01 hello maven

    安装省略,注意jdk的版本1.7: 目录:

  6. 异步消息处理机制——Handler用法

    Handler 1. Message Messsge是线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据,Message的what字段,除此之外还可以使用arg1和arg2字段 ...

  7. sql中的split方法

    ALTER function [dbo].[f_split](@SourceSql varchar(8000),@StrSeprate varchar(10))returns @temp table( ...

  8. iOS开发之git学习

    本人是参考廖雪峰的git学习的.他写的非常详细,我在这里就是把我学习中的总结以及碰到的坑写出来. /* 初始化git仓库:git init */ /* 添加文件到git仓库 */ 分两步: 第一步:追 ...

  9. 搜索+剪枝——运筹帷幄 (road.cpp)

    运筹帷幄 (road.cpp) [题目描述] 刘邦军行至迷糊林,见其中瘴气围绕,又有青狼猛虎之兽,难于前行. 已知迷糊林是一个共有n个结点的图,点与点之间共有m条道路相连接,每条路有参数t,c,分别表 ...

  10. elegant 的长整数加法 string 实现

    string strAdd(string &v1, string &v2){ string res = ""; ; int len1 = v1.size(), le ...