如此高效通用的分页存储过程是带有sql注入漏洞的

google中搜索“分页存储过程”会出来好多结果,是大家常用的分页存储过程,今天我却要说它是有漏洞的,而且漏洞无法通过修改存储过程进行补救,如果你觉得我错了,请读下去也许你会改变看法。

 

通常大家都会认为存储过程可以避免sql注入的漏洞,这适用于一般的存储过程,而对于通用分页存储过程是不适合的,请看下面的代码和分析!

 

一般的通用的分页存储过程代码如下:

 

通用分页存储过程

 

大家可以看到上面的存储过程中是通过一些步骤最终拼接成一个sql字符串,然后通过exec执行这个串得到分页的结果。

 

我们假定要做一个这样的查询,通过用户名UserName模糊查询用户,为了叙述方便,便于理解我们只考虑取第一页的情况,取出存储过程中取第一页的拼串行如下:

set @strSQL = 'SELECT TOP ' + str(@PageSize+ ' ' + @strGetFields + ' from [' + @tblName + ']  where ' + @strWhere + ' ' + @strOrder

 

为了便于说明问题,我们可以假定@pageSize20@strGetFields ‘*’@tblNameUserAccount,@strOrder’ ORDER  BY  ID DESC’ 那么上面一行可以写成如下形式:

set @strSQL = 'SELECT TOP 20 *  from [UserAccount]  where ' + @strWhere  + ' ORDER BY ID DESC’

 

我们可以假定用户输入的模糊用户名是: Jim’s dog

我们用SqlParameter传递参数给分页存储过程@strWhere 的值是:’UserName LIKE ‘’%Jim’’ dog%’’’(注意LIKE后边的字符串中的单引号已经全部变成两个单引号了),我们将这个值代入上面的@strSQL赋值语句中,如下:

 

set @strSQL = 'SELECT TOP 20 *  from [UserAccount]  where  UserName LIKE ''%Jim'' dog%'' ORDER BY ID DESC’

 

让我们写上声明变量的部分执行在查询分析器中测试一下,代码如下:

 

DECLARE @strSQL varchar(8000)
DECLARE @strWhere varchar(1000)
SET @strWhere = 'UserName LIKE ''%Jim'' dog%'''
set @strSQL = 'SELECT TOP 20 *  from [UserAccount]  where ' + @strWhere + ' ORDER BY ID DESC'
print @strSQL
exec (@strSQL)


大家可以把上面几行代码粘贴到查询分析器中执行一下,就可以看到下面的画面:


在消息的第一行,打印出了要执行的sql语句,很显然此语句的 LIKE ‘%Jim’ 后面的部分全部被截断了,也就是说如果用户输入的不是Jim’s dog而是Jim’ delete from UserAccount那么会正确的执行删除操作,传说中的sql注入就会出现了。

 

问题出现了,我们应该怎么解决问题?

1.  很显然我们使用SqlParameter传递参数已经将单引号替换成了连个单引号了,可是因为我们在数据库中拼串导致替换并不能解决问题。

2.  根据我的实验证明如果使用存储过程不可能解决这个问题,我们只有将这个存储过程要执行的拼串操作放到数据访问层去做,才可以避免这个问题。

 

如果大家有在存储过程中解决这个问题的办法,请不吝赐教。

备注:本文说的是MS SQL Server2000 的数据库,而非使用SQL 2005的新特性分页。

我的微博地址是:http://weibo.com/yukaizhao 我会把一些技术心得碎片写到微博中,欢迎关注。
posted @ 2007-03-09 18:16 玉开 阅读(8433) 评论(75) 编辑 收藏

 回复 引用   
#1楼2007-03-09 18:39 | jyk[未注册用户]
只能说找到了一个不好的方法。

在存储过程里面“组串”本来就没有什么优势可言的。存在注入也是很正常的。

http://blog.csdn.net/jyk/archive/2007/03/01/1518354.aspx

这是我的分页控件的思路,里面有几个分页的算法。

 回复 引用   
#2楼2007-03-09 18:47 | jyk[未注册用户]
我看了您的《三层开发中容易犯的错误》。

有几个地方您是否注意到了。

1、层与层之间的衔接,您注意到了吗?是否会有过渡的部分而无法准确的被划分到哪一层。

2、.aspx是UI层,这个没有什么争议,那么.aspx.cs文件呢?也是UI层吗?

3、业务逻辑的本质是什么?我觉得本质就是SQL语句,写在程序里也好,写在存储过程里也好,这个并不是重点。重点是如何体现业务逻辑。业务层到底放什么?能起到什么作用。


以上是瞎说的,说错了不要生气。


 回复 引用 查看   
#3楼2007-03-09 18:48 | 生米煮成稀饭      
注意:很显然我们使用SqlParameter传递参数已经将单引号替换成了双引号了,不是双引号,是两个单引号,通过存储过程传参数,不会有这个问题。
 回复 引用   
#4楼2007-03-09 19:00 | jyk[未注册用户]
您有没有试过替换成 四个“'” 就是 ''''



 回复 引用 查看   
#5楼[楼主]2007-03-09 19:05 | 玉开      
@生米煮成稀饭
谢谢更正,那个是笔误,不过你的说法不正确,你可以做个试验

 回复 引用 查看   
#6楼[楼主]2007-03-09 19:05 | 玉开      
@jyk
替换成四个也会截断,虽然不能注入了,但是也不能正常执行了

 回复 引用 查看   
#7楼[楼主]2007-03-09 19:10 | 玉开      
@生米煮成稀饭
因为是在存储过程中拼串,所以即使替换了也是不正确的。

 回复 引用 查看   
#8楼2007-03-09 19:24 | 生米煮成稀饭      
怎么会不正确呢?肯定是不会报错的
 回复 引用 查看   
#9楼[楼主]2007-03-09 19:24 | 玉开      
@生米煮成稀饭
你测试过吗?

 回复 引用 查看   
#10楼2007-03-09 19:30 | 生米煮成稀饭      
我们可以假定用户输入的模糊用户名是: Jim’s dog

我们用SqlParameter传递参数给分页存储过程@strWhere 的值是:’UserName LIKE ‘’%Jim’’ dog%’’’

这个是怎么来的?你这个@strWhere是在哪里拼凑出这个结果的?程序里面?还是sql里面?

 回复 引用 查看   
#11楼2007-03-09 19:31 | 生米煮成稀饭      
如果是在程序里面组合成整个’UserName LIKE ‘’%Jim’’ dog%’’’ 的话,你肯定是要进行字符串过滤的,如果只是把Jim’s dog 作为参数传进存储过程就不会出现你的问题了,我没有看你这个分页过程,但是,可以肯定的是,写的恰当的话,肯定不会出现你说的情况,因为我们一直都有在用分页存储过程。
 回复 引用 查看   
#12楼2007-03-09 19:36 | 生米煮成稀饭      
还有,说一句,刚看了下这个存储过程,top来top去的效率基本上是接近最差了!
 回复 引用 查看   
#13楼2007-03-09 19:49 | YaziMyWife      
代码没有缩进 看起来好不爽啊!!
 回复 引用 查看   
#14楼[楼主]2007-03-09 19:51 | 玉开      
@生米煮成稀饭
是在程序里面拼得然后传给存储过程。

 回复 引用 查看   
#15楼[楼主]2007-03-09 19:55 | 玉开      
@YaziMyWife
其实那个存储过程就是常用的用top的分页存储过程

 回复 引用 查看   
#16楼[楼主]2007-03-09 20:00 | 玉开      
@生米煮成稀饭
你可不可以把你经常用的存储过程贴出来看看

 回复 引用   
#17楼2007-03-09 20:11 | yzx110[未注册用户]
我一直没相信这样的存储过程能够避免SQL注入

因为拼SQL字符串,天知道组合SQL字符串的各个是什么内容。

因为你拼得SQL字符串并不是待参数的执行方式,那么理论上就是你传入什么东西那么拼接之后就是什么东西,既然是这样,那么怎样就确定不能SQL注入。

除非你在应用把引号等敏感字符过滤掉,但是这跟存储过程能避免SQL注入有什么关系呢?

 回复 引用 查看   
#18楼[楼主]2007-03-09 20:13 | 玉开      
@yzx110
谢谢,知音出现了,这确实是一种很大的安全漏洞

 回复 引用 查看   
#19楼2007-03-09 20:23 | 冲啊!为了钱~      
学习下,大家加油吧<br>

 回复 引用 查看   
#20楼2007-03-09 20:57 | Jeffrey Zhao      
“存储过程能够避免Sql注入”这个说法本来就是错误的!
出现Sql Injection的问题在于拼接字符串而不是有没有用存储过程。
在存储过程里拼接字符串也会造成Sql Injection,直接在代码写带参数的Sql语句然后设置参数也不会有Sql Injection。
// latency sql injection不在目前的讨论范围中

 回复 引用   
#21楼2007-03-09 21:17 | 电子网[未注册用户]
我看了您的《三层开发中容易犯的错误》。

有几个地方您是否注意到了。

1、层与层之间的衔接,您注意到了吗?是否会有过渡的部分而无法准确的被划分到哪一层。

2、.aspx是UI层,这个没有什么争议,那么.aspx.cs文件呢?也是UI层吗?

3、业务逻辑的本质是什么?我觉得本质就是SQL语句,写在程序里也好,写在存储过程里也好,这个并不是重点。重点是如何体现业务逻辑。业务层到底放什么?能起到什么作用。


以上是瞎说的,说错了不要生气。

 回复 引用   
#22楼2007-03-09 21:54 | ET电子技术网[未注册用户]
这么厉害




ET电子技术网
http://www.et-dz.com

 回复 引用   
#23楼2007-03-09 22:09 | jyk
1、一个很的方法,把单引号替换掉,因为在中文环境下,很少会用到单引号的。

2、转意,现在程序里面替换成全脚的单引号,组串之后exec之前在替换回来。

 回复 引用 查看   
#24楼2007-03-09 22:16 | ZergTant      
对,楼上说的对,中文全部替换成全角
英文的话,要过滤了,没有完美的sql injection解决放案,相比之下出现错误要比被injection好多了

 回复 引用   
#25楼2007-03-09 22:32 | yukaizhao[未注册用户]
@电子网
业务逻辑的本质是SQL语句应该是不正确的吧

 回复 引用   
#26楼2007-03-09 22:36 | yukaizhao[未注册用户]
@jyk
这种方法好像是不行的,因为发生注入就是在exec的时候,而你在exec的时候又替换回来岂不是和没有替换一样的;还是我没有理解你的话?

@ZergTant
因为分页是我们比较常用的存储过程,所以提出来说了

 回复 引用   
#27楼2007-03-09 22:39 | yukaizhao[未注册用户]
@ZergTant
如果只是分页的话还是有完美的解决方案的.

至于过滤得方法似乎不妥,因为用户可以搜索 Jim's dog 这是一个合情合理的搜索你不能不给出正确的搜索结果

 回复 引用 查看   
#28楼2007-03-09 22:42 | henry      
高不高率难道和sql有没有注入有关系?
最让人费解的是竟然用没有限制的输入字符作为SQL语句的部分.如果没有作过特殊处理有这问题是很正常的事情,无论是存储过程里的SQL语句还是程序端的SQL.

 回复 引用   
#29楼2007-03-09 22:49 | yukaizhao[未注册用户]
@henry
高效和注入确实没有关系,但是大家都有这样的知觉就是存储过程会更高效一些,所以标题就那么写了,还请不要见怪。

请问你是怎么处理分页的是用存储过程吗?

 回复 引用   
#30楼2007-03-10 07:52 | jyk
是在执行exec之前替换成两个单引号。

另一个方法就是替换成 “_”,模糊查询,只是结果会多出来一些。

 回复 引用   
#31楼2007-03-10 08:54 | yukaizhao[未注册用户]
@jyk
不管你替换成几个单引号都会被截断的,你可以做个试验看看,就明白了。

 回复 引用   
#32楼2007-03-10 09:55 | tinifish[未注册用户]
''%Jim'''' dog%''
 回复 引用   
#33楼2007-03-10 10:42 | yukaizhao[未注册用户]
@tinifish
这样写了,sql会认为你的字符串是:'%Jim'' 就是说会在第二个“成对单引号”的地方截断分页查询语句。

 回复 引用   
#34楼2007-03-10 11:01 | mj[未注册用户]
@tinifish
的确只能这样,把 Jim' dog 里的单引号替换成4个单引号,这样输出的sql语句就是:
SELECT TOP 20 * from [UserAccount] where UserName LIKE '%Jim'' dog%' ORDER BY ID DESC
再执行就正确了

 回复 引用   
#35楼2007-03-10 11:02 | mj[未注册用户]
@yukaizhao
不会的,sql语句里的两个单引号就转义为一个单引号字符了

 回复 引用   
#36楼2007-03-10 11:02 | mj[未注册用户]
两个连续的单引号
 回复 引用   
#37楼2007-03-10 11:17 | mj[未注册用户]
看了这篇文章还是相当的收教了 谢谢玉开

以后给存储过程传这样的参数的时候必须保证传入参数里的单引号在存储过程最终执行的sql语句里被两个连续的单引号替代
写存储过程的时候也要在注释和相关文档内按这个原则写清楚传入参数的替换规则

这样应该就没问题了吧

 回复 引用 查看   
#38楼2007-03-10 11:20 | 金色海洋(jyk)      
to:yukaizhao

我记得有一个叫做转义的东东的。

 回复 引用   
#39楼2007-03-10 11:26 | yukaizhao[未注册用户]
@金色海洋(jyk)
sql中的转义就是把一个英文的单引号换成两个英文的单引号,不知道你是不是指这个

 回复 引用 查看   
#40楼2007-03-10 11:41 | 金色海洋(jyk)      
string sql = " select * from tt where aa =' jim ''s home ' " 。

这样就是一条正确的语句。 ' jim ''s home ' 是一个字符串,不会被截断的。

相当于 jim's home 。

 回复 引用 查看   
#41楼2007-03-10 11:45 | 金色海洋(jyk)      
真的是难以想象会有人在存储过程里面组合字符串,看着都晕,说实在的lz的那个存储过程我都没有看出来是怎么组串的,这么写多累呀。

我是宁愿在程序里组合字符串!

 回复 引用   
#42楼2007-03-10 15:12 | yukaizhao[未注册用户]
@金色海洋(jyk)
可是因为分页存储过程必须用top + 记录数 所以就必须用拼串才能在存储过程里面实现。

 回复 引用   
#43楼2007-03-10 16:05 | James[未注册用户]
在防止SQL注入时,对于传入的字符串条件,我们应该对条件字段转义,进行单引号替换,
例如条件是查询用户名Jim' dog,替换后为Jim'' dog,加上LIKE后变为UserName LIKE '%Jim'' dog%',注意,中间的单引号变为两个单引号,前后的单引号为分隔符,不需要改变,
最后组成SQL语句:SELECT TOP 20 * from [UserAccount] where UserName LIKE '%Jim'' dog%' ORDER BY ID DESC,
这样的SQL就可以直接放到查询分析器里面执行了,没有问题。
楼主的语句中有这一句:SET @strWhere = 'UserName LIKE ''%Jim'' dog%'''
我们把转义符去掉后@strWhere的内容是这样的:UserName LIKE '%Jim' dog%'
很明显有语法问题,所以可以这样改:SET @strWhere = 'UserName LIKE ''%Jim'''' dog%'''

 回复 引用 查看   
#44楼2007-03-10 20:08 | henry      
@yukaizhao
呵呵,我重来不用存储过程分页,不过只是我个觉得没有必要.
往往一个查询符合条件的记录数不会超出几W条,如果超出那应该考虑相关业务是不是真的有必要(暂时还没有碰到一次获取十W条数据的情况).
用DataReader只遍历主索引字段是非常快(不相信可以遍历100W就知道),即使在几千W条数据中通过主索引获取记录所需的时间也是快得惊人:)

 回复 引用   
#45楼2007-03-10 22:58 | yukaizhao[未注册用户]
@henry
数据量大了全部取出来不是办法吧

 回复 引用 查看   
#46楼2007-03-11 14:31 | henry      
@yukaizhao
从另一角度看现实需求真的有需要获取这么大的数据量吗?在乎的可能只是当前查询的结果数量(是数量不是具体记录内容数),相信你也不会在二千条查询结果中以分页的方式来查找具体信息吧?(如果非要说大部分人喜欢这样做那没办法了)几千条数据分页还真有必要非要存储过程不可吗?

通用 分页
这里不错..

 回复 引用 查看   
#49楼2007-03-11 18:50 | 生米煮成稀饭      
无聊啊,这个帖子居然这么多人在说啊,还不知所云。。。
 回复 引用   
#50楼2007-03-12 09:30 | swz[未注册用户]
唉!......不說也罷
 回复 引用 查看   
#51楼[楼主]2007-03-12 13:09 | 玉开      
@生米煮成稀饭
用心看,你会有收获,否则,呵呵...

 回复 引用   
#52楼2007-03-13 09:43 | a[未注册用户]
link '%'+@keyword+'%'
 回复 引用 查看   
#53楼[楼主]2007-03-13 09:52 | 玉开      
@a
如果写成这样,确实就可以避免了,不过请注意这个通用的分页存储过程,要求传入的参数是@strWhereClause这样子,它才可以通用,否则就通用不了了,因为存在各种各样的条件和字段名。

 回复 引用   
#54楼2007-03-23 13:00 | anshen[未注册用户]
如约灌水
 回复 引用 查看   
#55楼2007-04-03 13:17 | kiler      
其实这种存储写了一点意义都没有,自己写程序动态生成一句sql不就好了,还要那么费劲的在存储过程里面写。
 回复 引用   
#56楼2007-09-09 21:28 | 小net[未注册用户]
我认为这么写比较好.
在SQL中构造SQL,天与鬼都不知道它里面是什么内容.只有到执行的时候才知道他是什么内容.这种构造的优点在于如果查询组合方式有N种那么如果用if else 那不太现实. 所以用构造SQL字符串,最后执行.
可是这样又会发生注入,其实很简单.定义个表变量,把第一次的条件搜索出来插入这个表变量,到了第二个条件的时候删除这个表变量中非第二次条件的数据.到了第三个条件,依次删除...

最后select 这个表变量.

不过这样带来了性能上的折损.不知道楼主意下如何.

 回复 引用   
#57楼2007-10-01 15:07 | 反对3333[未注册用户]
引用"还有,说一句,刚看了下这个存储过程,top来top去的效率基本上是接近最差了!"
你简直在瞎扯,MS SQL的top效率是最高,比什么max, not in高多了,你究竟自己比较测试过没有?

 回复 引用   
#58楼2007-10-01 15:09 | 反对3333[未注册用户]
--引用--------------------------------------------------
生米煮成稀饭: 还有,说一句,刚看了下这个存储过程,top来top去的效率基本上是接近最差了!
--------------------------------------------------------
top来top去的效率恰恰是最高的!

 回复 引用   
#59楼2007-10-01 15:17 | 反对3333[未注册用户]
对于楼主的问题,实际上是个众所周知得东西,这是sql的先天造成的,只要用字符串拼sql语句,就永远会存在漏洞,只有当sql变成强类型语言了,不依靠字符类型转来转去,才有可能根本避免.
现在的办法只有采用替换掉特殊字符的方式,只能牺牲一些功能,没有永远安全的东西,只有尽量更加安全,绝对安全就是以其他作为代价换来的,我只允许用户输入汉字,那就绝对安全.
等待数据库的进化改变吧.

 回复 引用   
#60楼2007-10-01 15:23 | 反对3333[未注册用户]
因为储存过程里top + 变量不能直接执行,只能用拼字符串用exec来执行,这本来就是微软脑袋有屎,为什么top后就不能跟个整型变量!@#@!#@!
 回复 引用 查看   
#61楼[楼主]2007-10-11 10:09 | 玉开      
@反对3333
这位哥们说的很有道理。

 回复 引用   
#62楼2007-10-19 15:07 | hayou[未注册用户]
就效率来说这个存储过程是我见过的效率最高的分页存储过程,我测试过100W条数据,每页20条纪录,取前100页几乎为0,1000以下也只有16MS左右,最后一页也就500MS,不知道是不是我没见过市面,单就效率来说,我觉得这个存储过程还是可以的,用TOP 远比那些用NOT IN/EXISTS的效率高几十倍,希望真正做过大数据量(100W以上)测试的朋友把你的存储过程贴出来和大家分享分享!期待中
 回复 引用   
#63楼2007-12-29 20:04 | qqq[未注册用户]
怎么调用?多表可不可以!!
 回复 引用 查看   
#64楼2008-04-29 03:18 | pwrjng      
效率来说还是很不错的,至少我觉得我够用了,但是有个问题,这个怎么链表查询捏?
 回复 引用 查看   
#65楼2008-07-18 17:24 | Net205 Blog      
搜索blog找到这篇老文章,去年的,我说一下我的想法。
--代码中的@strSearch假设为存储过程的参数
按你的代码写的(存在SQL注入的写法)
declare @strSearch varchar(100)
set @strSearch = 'Jim''dog'

DECLARE @strSQL varchar(8000)
DECLARE @strWhere varchar(1000)
SET @strWhere = 'UserName LIKE ''%'+ @strSearch +'%'''
set @strSQL = 'SELECT TOP 20 * from [UserAccount] where ' + @strWhere + ' ORDER BY ID DESC'
print @strSQL
exec (@strSQL)

解决办法:
declare @strSearch varchar(100)
set @strSearch = 'Jim''dog'

DECLARE @strSQL nvarchar(4000)
DECLARE @strWhere varchar(1000)
SET @strWhere = 'UserName LIKE ''%@strSearch%'''
set @strSQL = 'SELECT TOP 20 * from [UserAccount] where ' + @strWhere + ' ORDER BY ID DESC'
print @strSQL
exec sp_executesql @strSQL,N'@strSearch varchar(100)',@strSearch

试验过

 回复 引用 查看   
#66楼[楼主]2008-07-21 18:13 | 玉开      
@Net205 Blog
这是一个思路吧,where条件通常是多变的。

按照你的这个说法,的确会出现你所预期的"sql注入".
在说明我的想法之前,我先说一下什么是"存储过程能够阻止SQL注入攻击".其实所谓是sql注入攻击.就是利用现有的sql,然后往里面添加参数,使之构造成非本意的sql语句.而之所以能够达到这个目的,无非是利用sql中有特殊意义的字符,截断原有sql语句,然后将带有我们目的的sql脚本在该次sql操作中执行.所以,要阻止sql注入攻击,对于我们开发人员来讲:就是替换掉这些特殊的字符,并且使之达到原来的目的.
那么为什么很多书籍都会提到"存储过程可以防止sql注入攻击呢?".我们都知道任何带有判断意义的话,都需要一定的前提条件的.所以,我们都掉入了那些书籍的陷阱了.存储过程要防止sql注入攻击,第一是需要借助输入参数的(输入参数的传递是需要借助.net的parameter(包括sql的,oracle的等等).第二点是在借助输入参数的前提下,我们必须保证你的存储过程本身没有sql注入语句的存在.在这两点的基础上,我们可以说"存储过程可以防止sql注入攻击".
而这篇文章所饭的错误非常的严重,也很容易让别人困惑:第一,你定义了参数,可是你的参数是在sql中给参数赋值.第二,你想当然的对某些特定字符进行了转换.正是这两个错误的做法,才支撑起你这篇文章的论点.
就已英文的单引号为例.
输入参数为: @strWhere 你真正的查询条件是(要查找所有名字中带有Jim'dog的人)
传递给.net的sqlparameter(不再列举其它类型的输入参数):
UserName LIKE '%Jim''dog%'

转换成sql后
'UserName LIKE ''%Jim''''dog%'''
呵呵,这是我通过sql监视器看到的转换结果

所以,在满足上述两点的基础上.我们才有了"存储过程能够阻止SQL注入攻击"的结论
 回复 引用 查看   
#69楼2008-11-28 16:39 | 一味      
@弄个名字真难
看完这个帖子,终于遇到正确的回答。

 回复 引用 查看   
#70楼[楼主]2008-11-28 17:36 | 玉开      
@一味
拼串是危险的,用参数是安全的,但是也不能用参数来拼串。

 回复 引用 查看   
#71楼2009-09-20 23:57 | 35kc      
其实自己可以对传入参数进行过滤或转义,任何没有经过处理的参数传入给SQL都可能出现注入漏洞。比如单引号的转义是双单引号,单百分号的转义是双百分号。网上找个防注入对URL传入或是POST传入参数进行转义即可。
 回复 引用 查看   
#72楼2010-07-09 22:46 | John Liu      
只要是动态sql,就存在注入的问题,既然要通用,就要用表名,字段名做变量,就要用动态sql,就存在这个问题。想解决只要在调存储过程的时候先进行过滤吧。
 回复 引用   
#73楼2010-12-20 14:15 | angelybaby[未注册用户]
其实这个很简单的,主要是在内容写入数据库的时候将"'","<",">"等等可能用来注入的字符进行过滤,如将"'"转换成[1],"<"转换成[2],以此类推,当然这个是自定义。
然后将过滤后的内容直接存入数据库即可,到时候在搜索如job's name这样带有"'"的内容时,同样的将"'"转换成[1]即job[1]s name,以这样的方式进行查询,然后输出到页面的时候将[1]再次转换成"'"即可!

 回复 引用 查看   
#74楼2010-12-23 17:45 | Jacklondon Chen      
VelocityWeb 1.3 发布,增加 SQL 分页支持!!支持多种数据库
http://blog.csdn.net/jacklondon/archive/2008/08/23/2816824.aspx

 回复 引用   
#75楼2011-11-18 20:03 | 存储[未注册用户]
我叫Matt,我在代表戴尔公司。我觉得,你写得,真的很好。我想,存储过程就是常用的用top的分页存储过程。。
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 669617 wcduORx3XcA=