最近在做数据库的应用,在使用ado过程中发现一些问题,查了一些资料,很少有对其做详细的介绍,只是提供了简单的用法。
很多在访问过程中使用recordset对象,或者无返回值的语句使用connection对象的execute方法。这些方法使用起来确实很简单,特别是execute, 在创建了连接后就不用再创建其它对象就可以执行语句。但是相关问题也同时曝露出来,当有参数传递时,需要对数据进行过滤,来防范sql注入攻击,对数据的格式要求就会非常严格,用户使用也会失去一些特色。
由于要用ADO访问MySql的存储过程,对Command对象进行了一些研究, 首先就是"?"语法。这个东西在MySql的Prepare Statement中经常用到,如果用过的话,大家应该对它很熟悉。“?”表示参数的占位符,参数会以变量的形式传递进去。当传递的参数遇到“1=1”之类的语法,它也只会作为一个字符串,不会转换成语句执行。这样以后,上面的sql注入攻击便对其无能为力。
令人高兴的是,Command支持这种语法。这样,我们写的语句就更安全。
不过幸运的是,我在用C++使用此命令时,发现Execute的第二个参数是一个数组。虽然我在C++中用相同的方法调用失败,只能用AddParam来代替,但在asp中确调用成功。
很多在访问过程中使用recordset对象,或者无返回值的语句使用connection对象的execute方法。这些方法使用起来确实很简单,特别是execute, 在创建了连接后就不用再创建其它对象就可以执行语句。但是相关问题也同时曝露出来,当有参数传递时,需要对数据进行过滤,来防范sql注入攻击,对数据的格式要求就会非常严格,用户使用也会失去一些特色。
由于要用ADO访问MySql的存储过程,对Command对象进行了一些研究, 首先就是"?"语法。这个东西在MySql的Prepare Statement中经常用到,如果用过的话,大家应该对它很熟悉。“?”表示参数的占位符,参数会以变量的形式传递进去。当传递的参数遇到“1=1”之类的语法,它也只会作为一个字符串,不会转换成语句执行。这样以后,上面的sql注入攻击便对其无能为力。
令人高兴的是,Command支持这种语法。这样,我们写的语句就更安全。
set Conn=Server.CreateObject("ADODB.Connection")
Conn.Open "driver={MySQL ODBC 3.51 Driver};server=127.0.0.1;port=3307;uid=root;pwd=stephen;database=ctbsdb"
set cmd = server.CreateObject("adodb.command")
set cmd.ActiveConnection = conn
‘设置变量,返回的值要保存在这里
cmd.CommandText="set @szErr123 = 0;"
cmd.Execute()
cmd.CommandText="call sp_test(?,@szErr123);" ‘?号的值为下面在Execute中传入的值,建议普通的sql语句也采用这种方式,可以防止sql注入攻击
set rs = cmd.Execute(,ival) '前面的" , "号是有的,不要去掉,不是笔误
此例是关于Mysql的。在上一篇文章中已经写过,网上也有关于此方法的介绍。不过上面只是传递一个参数,没有传递多个参数的情况,网上搜过好多资料,也没有介绍,也可能是我没有搜到。
不过幸运的是,我在用C++使用此命令时,发现Execute的第二个参数是一个数组。虽然我在C++中用相同的方法调用失败,只能用AddParam来代替,但在asp中确调用成功。
dim pArr(1)
cmd.CommandText="SELECT * FROM test WHERE id=? AND name=?"
pArr(0) = 12
pArr(1) = "abc"
set rs = cmd.Execute(, pArr)
代码就这么简单。另处,在使用mysql时,我在asp中使用AddParam的方法一直没有成功。假如你为此问题而烦恼的话, 不防使用此方法。而且我也推荐使用此方法,这将为你省不少时间。对于效率的问题,我没有测过,有兴趣的话,可以试一下,如果谁试过也告诉我一下^^。