为了防止程序SQL语句错误以及SQL注入,单引号必须经过处理。有2种办法:

1、使用参数,比如SELECT * FROM yourTable WHERE name = @name;

在C#中使用SqlParameter parameter = new SqlParameter("@name", objValue);来添加参数,懒得写SqlDbType这东西了,因为不写也完全可以,只需要参数名和值。

在JAVA中就是用预处理PreparedStatement来添加参数。

2、如果不用参数,而用字符串拼接的话,单引号必须经过判断并替换,在数据库中,用2个单引号代表1个实际的单引号。所以,如果是拼接方式,需要用String.Replace("'", "''")来替换一下,将1个单引号替换为2个就没有问题了。

SQL语句中,字符串是用两个单引号包起来标示的,所以要在字符串里保留单引号,必须要转义,而转义很简单,就是两个连续的单引号就表示一个单引号字符。

再说一下C#中的模糊查询,为了避免单引号,我们使用参数的方式,下面的语句是不对的:

SELECT * FROM yourTable WHERE name LIKE ‘%@name%’;在这个句子中,’%@name%’被整体当作一个字符串来处理,你无论如何查询不到结果。修改一下,SELECT * FROM yourTable WHERE name LIKE @name;然后添加参数的时候这么添加:

new SqlParameter("@name", "%" + categoryName + "%"); 这下就没问题了,正常查询,你输单引号照样查。

一. SQL Injection及其防范的基本知识

可能大家都知道,SQL注入主要是利用字符型参数输入的检查漏洞。

比如说,程序中有这样的查询:

string sql = "SELECT * FROM SiteUsers WHERE UserName=" + userName + "";

其中的userName参数是从用户界面上输入的。

如果是正常的输入,比如"Peter",SQL语句会串接成:

"SELECT * FROM SiteUsers WHERE UserName=Peter";

如果攻击者输入的是下面的字符串:

"xxx; DROP TABLE SiteUsers WHERE 1=1 or UserName=xxx"

此时SQL语句会变成下面这个样子:

"SELECT * FROM SiteUsers WHERE UserName=xxx; DROP TABLE SiteUsers WHERE 1=1 or UserName=xxx";

其结果,得到执行的是两个SQL语句,第二个语句的后果就比较严重了。

防止注入的方法其实很简单,只要把用户输入的单引号变成双份就行了:

string sql = "SELECT * FROM SiteUsers WHERE UserName=" + userName.Replace("","") + "";

这样,如果输入的是上面那种恶意参数,整个SQL语句会变成:

"SELECT * FROM SiteUsers WHERE UserName=xxx; DROP TABLE SiteUsers WHERE 1=1 or UserName=xxx";

被执行的还是一个SQL语句,整个粗体部分都成为参数值。

一般的做法,是在程序中统一调用下面这样的共通函数,对参数进行处理:

private string SafeSqlLiteral(string inputSQL)

{

return inputSQL.Replace("'", "''");

}

由于很多人会疏忽这种单引号替换,所以真正安全的做法是使用参数化查询。

二. 参数化查询

在ADO.NET中,提供了一种参数化查询方法,可以替代上面这种拼接SQL语句的做法。

参数化查询的具体实现是:

(1)组织一个夹带参数名的SQL语句,作为SqlCommand的CommandText。

(2)使用Parameters.Add方法设置参数值。

(3)执行SqlCommand。(这个步骤跟上面那种拼接SQL的办法是一样的。)

下面是一个例子:

string sql = "SELECT T2.dep_code, T2.dep_name FROM DEP ";

sql += " WHERE T2.dep_name like (%+ @Param + %) ";

SqlCommand sqlCommand = new SqlCommand(sql,cn);

sqlCommand.Parameters.Add(new SqlParameter("Param", s));

其中的@Param就是参数名,s则是用户输入的查询条件字串。

(顺便注:Oracle查询语句参数用问号表示,不是"@参数名"的形式。)

使用这种参数化查询的办法,防止SQL注入的任务就交给ADO.NET了。

如果在项目中统一规定必须使用参数化查询,就不用担心因个别程序员的疏忽导致的SQL注入漏洞了。

但是,问题还没有完,SQL注入的漏洞是堵住了,但是查询结果的正确性,参数化查询并不能帮上什么忙。

三. 通配符问题

如果使用LIKE语句进行模糊查询,会有一些特殊的通配符问题。

SQL Server的通配符包括下划线(_)和百分号(%),分别表示单个字符和任意多字符。

如果用户输入参数中包括这些通配符,就会出现结果不正确的问题。

比如说:

WHERE T2.name like (%+ @Param + %)

如果用户输入下划线,他期待的结果应该是name字段值含有下划线的记录,但是结果是所有记录都会被查询出来。输入百分号也是如此。

为此,在将用户输入的内容作为参数值传入之前,必须进行通配符的转义处理(英文叫做Escape),也就是说,如果用户输入的查询条件中含有通配符,必须将这些字符作为数据而不是通配符来对待。

在SQL Server的查询语句中,将通配符转义为普通数据的方法是用方括号括起来。

比如说,如果想要查询带有下划线的字段,正确的写法是:

WHERE T2.name like (%+ [_] + %)

同样,如果想要查询带有百分号的字段,正确的写法是:

WHERE T2.name like (%+ [%] + %)

所以,即使使用参数化查询,也必须在将用户输入的内容当作参数值传入SqlCommand.Parameters之前,先进行下面的处理:

s = s.Replace("%", "[%]");

s = s.Replace("_", "[_]");

四. 方括号问题

如果你足够细心,可能发现了还有一个方括号问题。

既然方括号是用来界定数据内容的,那么如果用户输入的查询参数本身就包括方括号时,会出现什么结果呢?

根据用户的期望,如果输入一个方括号,查询结果中应该只包括那些字段值中含有方括号的记录。

但是实验结果表明,如果是没有配成对的单个左方括号,查询时这个左方括号会被忽略。

也就是说,下面这个语句:

WHERE T2.name like (%+ [ + %)

等价于下面这个语句:

WHERE T2.name like (%+ + %)

这将导致查询结果中包含表中的全部记录,就像没有任何过滤条件一样。

为此,如果用户输入的查询条件中含有左方括号的话,还必须对左方括号进行转义:

s = s.Replace("[", "[[]");

注:右方括号没有这个问题。

五. 其他注意事项

按照微软的建议,凡是有可能导致问题的输入,可以在UI部分就进行检查并拒掉。

这些可疑输入包括:

分号(;):多个查询语句之间的分隔符,注入攻击时的恶意查询语句往往就是第二个查询语句。

单引号():字符串数据分隔符,这是最危险的,前面已经讨论了。

注释符(–或者/*,*/):有些数据库可以利用注释设置一些查询引擎的行为,比如如何利用索引等。

xp_:扩展存储过程的前缀,SQL注入攻击得手之后,攻击者往往会通过执行xp_cmdshell之类的扩展存储过程,获取系统信息,甚至控制、破坏系统。

六、结论

为了防止SQL注入,同时避免用户输入特殊字符时查询结果不准确的问题,应该做两件事:

(1)使用参数化查询。

(2)在使用用户输入的字符串数据设置查询参数值之前,首先调用下面的共通处理函数:

private static string ConvertSql(string sql)

{

//sql = sql.Replace("", ""); // ADO.NET已经做了,不要自己做

sql = sql.Replace("[", "[[]"); // 这句话一定要在下面两个语句之前,否则作为转义符的方括号会被当作数据被再次处理

sql = sql.Replace("_", "[_]");

sql = sql.Replace("%", "[%]");

return sql;

}

mysql对单引号的模糊查询_SQL语句中的单引号处理以及模糊查询相关推荐

  1. mysql同姓查询_sql语句中在学生信息表中查询同姓的学生姓名

    展开全部 1.创建一个bai测试表,如下图 createtabletest_duname(idint,namevarchar2(20))zhi: 2.插入测试数据dao,如下图 insertintot ...

  2. mysql数据表中取几列_MySQL查询数据表中数据记录(包括多表查询)

    MySQL查询数据表中数据记录(包括多表查询) 转自:http://www.baike369.com/content/?id=5355 在MySQL中创建数据库的目的是为了使用其中的数据. 使用sel ...

  3. MySQL查询数据表中数据记录(包括多表查询)

    MySQL查询数据表中数据记录(包括多表查询) 在MySQL中创建数据库的目的是为了使用其中的数据. 使用select查询语句可以从数据库中把数据查询出来. select语句的语法格式如下: sele ...

  4. 03-映射文件的sql语句中 #{} 和 ${} 的区别以及实现模糊查询

    映射文件的sql语句中 #{} 和 ${} 区别以及实现模糊查询 目录 sql 语句中的 #{} #{} 模糊查询错误用法 #{} 实现模糊查询 sql 语句中的 ${} ${} 实现模糊查询 #{} ...

  5. 【MyBatis笔记】03-映射文件的sql语句中 #{} 和 ${} 的区别以及实现模糊查询

    映射文件的sql语句中 #{} 和 ${} 区别以及实现模糊查询 sql 语句中的 #{} #{} 模糊查询错误用法 #{} 实现模糊查询 sql 语句中的 ${} ${} 实现模糊查询 #{} 与 ...

  6. c语言 switch 单引号,在switch语句中表示单引号的错误

    我必须删除文件中的所有注释.引号内的注释分隔符应视为文本,并且必须打印到屏幕上.评论内的评论被视为其他评论,必须删除.在switch语句中表示单引号的错误 我在遇到下面的switch语句时遇到了单引号 ...

  7. mysql单引号转义_sql语句中使用单引号'作为转义字符

    在SQL中,我们都知道单引号 ' 表示字符串的开始和结束符号,如: select * from students where name = '小明'; 但如果字符串里面有单引号时,应该怎么查询呢? 这 ...

  8. mysql预编译语句拼接查询_SQL语句预编译(查询)

    SQL语句预编译 SQL语句预编译能预防SQL注入提高安全性,是因为SQL语句在程序运行前已经进行了预编译,在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析,编译和优化,对应的执行计划也会 ...

  9. python单引号双引号三引号_python中的单引号、双引号和三引号有何区别

    单引号和双引号 在Python中我们都知道单引号和双引号都可以用来表示一个字符串,比如str1 = 'python' str2 = "python" str1和str2是没有任何区 ...

  10. js拼装html单引号双引号,js、html中的单引号、双引号及其转义使用

    js.html中的单引号.双引号及其转义使用 在js中对相关字符做判断或取值的时候很多情况下都会用到这些. ------ 在一个网页中的按钮,写onclick事件的处理代码,不小心写成如下: IE提示 ...

最新文章

  1. 牵引力教育设计总监解密9大2018潮流UI设计趋向
  2. 关于第十六届全国大学生智能汽车竞赛总决赛的规则建议
  3. JWT对称加密非对称加密
  4. CentOS7,zabbix3.4通过,zabbix-Java-gateway监控Tomcat
  5. Funambol DM 安装过程
  6. 在Spring框架中使用SQL存储过程
  7. linux meta 18.0.1 系统安装nodejs
  8. 联想Y450电源管理无法调节屏幕亮度的解决办法
  9. python还可以这么玩?用Python把视频转换为字符动画(含音频、高清、彩图)【附源码】
  10. Android 7 soter,开通微信人脸支付 OPPO Find X 成首发安卓手机
  11. html如何显示ppt首页,aspx怎样显示ppt转换的html页面
  12. pytorch中实现Balanced Cross-Entropy
  13. 最新版sketch插件怎么安装,3步搞定
  14. 基于canvas画布的星空效果
  15. 小程序毕设作品之微信二手交易小程序毕业设计成品(8)毕业设计论文模板
  16. 使用rewrite规则实现将所有到a域名的访问rewrite到b域名
  17. 51单片机汇编语言基本程序
  18. sql和mapinfo处理
  19. 力扣(LeetCode)799. 香槟塔(C++)
  20. ☀️ 学会编程入门必备 C# 最基础知识介绍(二)——进制、原码反码、基本语法、数据类型、类型转换

热门文章

  1. 拼多多---多多果园怎么玩
  2. Python也有对象了哈哈哈哈哈哈嗝
  3. Spring系列第2篇:控制反转(IoC)与依赖注入(DI),晦涩难懂么?
  4. 需要记住的的资料网址
  5. 今天我们谈谈关于java自学的那些事儿(为那些目标模糊的码农们)
  6. ohoTips - 最屌的消息弹窗工具!
  7. 移动硬盘无法读取是怎么回事?
  8. gazebo可以另存为world
  9. 如何通过织云Lite愉快地玩转TSW
  10. 《炬丰科技-半导体工艺》化学添加剂对KOH 溶液中Si表面反应性的影响