当前位置:编程学习 > C#/ASP.NET >>

怎么写关于“IN”操作符的SQL语句的参数化命令

大家知道为了防止SQL注入式攻击,在查询数据库的时候最好用ADODB.Command创建参数化的SQL查询语句

比如

    OdbcConnection oConn = new OdbcConnection(this.dsn);
    oConn.Open();
    string sqltext = "SELECT * FROM user WHERE id = ?";
    OdbcCommand oCmd = new OdbcCommand(sqltext, oConn);
    oCmd.Parameters.Add("UserId", OdbcType.Int).Value = 888;
    OdbcDataReader oDr = oCmd.ExecuteReader();

但是有个问题来了,我想用SQL的In操作符
比如这样的SQL语句:SELECT * FROM user WHERE id IN (777, 888, 999)
我就不知道怎么写参数化命令了

我写成下面这样也不对

    string sqltext = "SELECT * FROM user WHERE id IN (?)";
    OdbcCommand oCmd = new OdbcCommand(sqltext, oConn);
    oCmd.Parameters.Add("UserId", OdbcType.Int).Value = "777,888,999";

希望大侠帮帮忙
--------------------编程问答-------------------- oCmd.Parameters.Add("UserId", OdbcType.Int).Value = "777,888,999";
UserId和你那个问号有啥关系,你的参数应该有个名字 --------------------编程问答--------------------  string sqltext = "SELECT * FROM user WHERE  charindex(','+rtrim(id)+',',','+?+',')>0"; --------------------编程问答-------------------- UserId和?号是对应起来的
SQL语句里面的?号是和参数按顺序对应起来的

比如如果SQL语句里面有两个?号,下面就必须要添加两个参数,和这两个问号按顺序一一对应起来
这样的方式是能通过编译并运行正常的 --------------------编程问答-------------------- lz那样写,是把777,888,999看成一个字符串了
也就是 id in('777,888,999')
--------------------编程问答-------------------- string sqltext = "SELECT * FROM user WHERE id IN (@UserId)"; --------------------编程问答-------------------- hjywyj大侠,我也不知道该怎么把这三个值弄进去,就随便写了一下
如果能有哪个添加参数的命令能够构成 id IN (777,888,999) 这样的SQL语句就最完美也最方便了

jia5255大侠,把?号改成@UserId的效果是一样的,没有解决问题 --------------------编程问答-------------------- 添加多个参数试试,比如 in(@p1,@p2,@p3) 然后添加三个参数并赋值 --------------------编程问答--------------------  string sqltext = "exec('SELECT * FROM user WHERE id IN (?)')";
 OdbcCommand oCmd = new OdbcCommand(sqltext, oConn);
 oCmd.Parameters.Add("UserId", OdbcType.Int).Value = "777,888,999"; --------------------编程问答--------------------
引用 8 楼 root_lee 的回复:
string sqltext = "exec('SELECT * FROM user WHERE id IN (?)')";
 OdbcCommand oCmd = new OdbcCommand(sqltext, oConn);
 oCmd.Parameters.Add("UserId", OdbcType.Int).Value = "777,888,999";
……

这样是会有问题的,UserId是整数类型,777,888,999是不会被SQL当成三个整数的
如果OdbcType.Int改成Char类的,又会报类型不匹配
--------------------编程问答-------------------- dongxinxi大侠,分成三个参数是能暂时解决问题,但是用IN是因为IN里面的值的个数是不定的哦 --------------------编程问答--------------------
引用 2 楼 hjywyj 的回复:
string sqltext = "SELECT * FROM user WHERE  charindex(','+rtrim(id)+',',','+?+',')>0";

试试这个 --------------------编程问答-------------------- hjywyj大侠,谢谢你,这个方法能用
不过如果能有构成 id IN (777,888,999) 这样的SQL语句就最完美也最方便了 --------------------编程问答--------------------
引用 12 楼 yezzi 的回复:
hjywyj大侠,谢谢你,这个方法能用
不过如果能有构成 id IN (777,888,999) 这样的SQL语句就最完美也最方便了

那你就拼接字符串吧 --------------------编程问答--------------------
http://www.w3school.com.cn/sql/sql_in.asp --------------------编程问答--------------------
拼接我也想,但是用参数化命令安全些 --------------------编程问答-------------------- 用这种方法:
string s = "基础日语,普通物理学,声学";
string sqlStr="select * from 选课信息 where 课程 in (" + Regex.Replace(s, @"[^,]+", "?") + ")";
添加参数时用:
foreach(string str in s.Split(','))
     cmd.Parameters.AddWithValue("?",str);

由于Regex.Replace(s, @"[^,]+", "?")的值必定是?,?,?这种形式,所以是安全的,不会被注入。 --------------------编程问答-------------------- 哇~强人那~
希望大家发散思维,还能有更多的方法 --------------------编程问答-------------------- in(@id) 这就行啊.    sql前自己构造。。 把@id当做整体 --------------------编程问答-------------------- 既然你是防SQL注入,那么,你的Select为什么要写成这种格式呢?
直接在后台拼写SQL不是来得更简单?
防SQL注入,而不是防你的Select. 
楼主同学可以先理解一下哪些情况需要防Sql注入吧。了解清楚后,你就不会问这个问题了。 --------------------编程问答-------------------- IN操作符用拼接SQL的话,也是有注入的风险的

比如前台网页有几个复选框可以多选user的id,提交到后台是“777, 888, 999”的形式,再拼接到“IN()”里面,是很有可能被注入的哦 --------------------编程问答--------------------
引用 9 楼 dongxinxi 的回复:
引用 8 楼 root_lee 的回复:string sqltext = "exec('SELECT * FROM user WHERE id IN (?)')";
 OdbcCommand oCmd = new OdbcCommand(sqltext, oConn);
 oCmd.Parameters.Add("UserId", OdbcType.Int).Valu……

如果直接写成oCmd.Parameters.Add("UserId", "777,888,999");了 --------------------编程问答-------------------- oCmd.Parameters.Add("UserId", "777,888,999");这样不行
SQL会当成 WHERE id IN ('777,888,999')
但实际应该是 WHERE id IN (777,888,999) --------------------编程问答-------------------- 上面我这个回复无用,请忽略。。。。 --------------------编程问答-------------------- 哎,真是纠结的程序员啊?这个不行就换一种思路被 --------------------编程问答--------------------
求思路。。。 --------------------编程问答-------------------- 储存过程或者用exists语句 --------------------编程问答-------------------- 既然是整形直接判断不就行了吗?
字符型才有注入可能 --------------------编程问答-------------------- http://www.mywebsite.com/sj/test/test.aspx?name=sviergn&x=true#stuff --------------------编程问答-------------------- IN使用和like使用都差不多吧先把参数构造好如
 oCmd.Parameters.Add("UserId", OdbcType.Int).Value ="%"+ "888"+"%";再把这个作为参数传入就可以实现了! --------------------编程问答-------------------- oCmd.Parameters.Add("UserId", OdbcType.Int).Value = "'777','888','999'";
这样不行么? --------------------编程问答-------------------- 我只是进来学习学习的 --------------------编程问答--------------------
引用 30 楼 asd100230520 的回复:
oCmd.Parameters.Add("UserId", OdbcType.Int).Value = "'777','888','999'";
这样不行么?


这样不行的,SQL会吧“'777','888','999'”认为是一个字符串的值,而不是三个分开的数字 --------------------编程问答-------------------- in 只能exec拼接sql
否则你就需要有多少个参数,你就要传多少个参数in (@p1,@p2)..不管你这个是在程序里拼接还是在Sql里拼接,看看也恐怖啊 --------------------编程问答-------------------- 另外,如果你能保证你的in一定不是通过前台获取到的数据组成,直接拼接sql并不存在什么Sql注入问题,如果有问题。。。那也是你的数据库本身就有问题了
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,