通过C#中的参数在SqlCommand中的字符串列表
在CI中使用SqlCommand创建了一个查询,该查询在where子句中包含IN(list ...)部分。我不需要遍历我的字符串列表来生成列表,而是需要查询(如果在sqlInjection中考虑,则很危险)。我以为我可以创建一个像这样的参数:
SELECT blahblahblah WHERE blahblahblah IN @LISTOFWORDS
然后在代码中,我尝试添加一个像这样的参数:
DataTable dt = new DataTable(); dt.Columns.Add("word", typeof(string)); foreach (String word in listOfWords) { dt.Rows.Add(word); } comm.Parameters.Add("LISTOFWORDS", System.Data.SqlDbType.Structured).Value = dt;
但这是行不通的。
问题:
- 我在尝试一些不可能的事情吗?
- 我采取了错误的方法吗?
- 我在这种方法上有错误吗?
谢谢你的时间 :)
解决方案
回答
我们想考虑该列表的来源。通常,该信息位于数据库中的某个位置。例如,代替此:
SELECT * FROM [Table] WHERE ID IN (1,2,3)
我们可以使用如下子查询:
SELECT * FROM [Table] WHERE ID IN ( SELECT TableID FROM [OtherTable] WHERE OtherTableID= @OtherTableID )
回答
我建议将参数设置为以逗号分隔的值字符串,并在SQL中使用Split函数将其转换为值的单列表,然后可以使用IN功能。
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648拆分函数
回答
如果我理解正确,则我们正在尝试将列表作为SQL参数传递。
有些人以前曾尝试过这种方法,但收效甚微:
将数组传递到存储过程
SQL 2005中的数组和列表
在不进行字符串操作的情况下将值数组传递给SQL Server
使用MS SQL 2005的XML功能将值列表传递给命令
回答
如果要将列表作为字符串传递给参数,则可以动态构建查询。
宣告@query varchar(500)
SET @query ='在('+ @list +')'中选择SELECT等等
执行(@query)
回答
我曾经遇到过同样的问题,我认为现在有直接在ADO.NET API上执行此操作的方法。
我们可能会考虑将单词插入到一个临时表中(加上查询ID或者其他内容),然后从查询中引用该临时表。或者动态创建查询字符串,并避免通过其他措施(例如正则表达式检查)进行SQL注入。
回答
我们尝试做的事情是可能的,但不能使用当前的方法。对于SQL Server 2008之前的所有可能解决方案,这是一个非常常见的问题,需要在性能,安全性和内存使用方面进行权衡。
此链接显示了SQL Server 2000/2005的一些方法
SQL Server 2008支持传递表值参数。
我希望这有帮助。
回答
- 我在尝试一些不可能的事情吗?
不,这不是不可能的。
- 我采取了错误的方法吗?
方法不起作用(至少在.net 2中)
- 我在这种方法上有错误吗?
如果可能,我会尝试" Joel Coehoorn"解决方案(第二个答案)。
否则,另一种选择是发送一个"字符串"参数,其所有值都由分隔符分隔。编写动态查询(基于字符串中的值进行构建),然后使用" exec"执行它。
另一个解决方案是o直接从代码构建查询。像这样的东西:
StringBuilder sb = new StringBuilder(); for (int i=0; i< listOfWords.Count; i++) { sb.AppendFormat("p{0},",i); comm.Parameters.AddWithValue("p"+i.ToString(), listOfWords[i]); } comm.CommandText = string.Format(""SELECT blahblahblah WHERE blahblahblah IN ({0})", sb.ToString().TrimEnd(','));
该命令应如下所示:
SELECT blah WHERE blah IN (p0,p1,p2,p3...)...p0='aaa',p1='bbb'
在MsSql2005中," IN"仅使用256个值。