如何使用IN sql关键字构建参数化查询?

时间:2011-12-27 15:46:51

标签: c# sql-server-ce

这就是我尝试过的&失败了:

      string sql = "... WHERE [personID] IN (@sqlIn) ...";
      string sqlIn = "1,2,3,4,5";
      SqlCeCommand cmd.Parameters.Add("@sqlIn", SqlDbType.NText).Value = sqlIn;

      SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
      da.Fill(ds); // > Error

错误详情:

  

ntext和image数据类型不能在WHERE,HAVING,GROUP BY,ON或IN子句中使用,除非这些数据类型与LIKE或IS NULL谓词一起使用。

我不能将所有ID作为一个参数传递吗?我应该逐个添加所有ID吗?

P.S:注意SqlCE

2 个答案:

答案 0 :(得分:5)

您不能将其作为单个参数进行参数化。您的查询在单个值上执行“in”,因此基本上是:

... Where personId = '1,2,3,4,5'

(给或参数)。这通常是 也是无效或次优的相等测试,当然不是你想要查询的内容。

选项;

  • 使用原始连接:通常涉及SQL注入风险,并允许重复使用差的查询计划
  • 在完整的SQL服务器上:使用UDF拆分单个参数
  • 在完整的SQL服务器上,使用TVP
  • 动态添加参数,并将各种@ param3等添加到TSQL

最后一个是最可靠的,“dapper-dot-net”有一个内置功能为你做这个(因为它通常是需要的):

int[] ids = ...
var rows = conn.Query<SomeType>(
    @"... Where Id in @ids",
    new { ids }).ToList();

当通过dapper-dot-net运行时,将在“ids”中为每个项添加一个参数,为其提供正确的值等,并修复SQL以便执行,例如:

"... Where Id in (@ids0, @ids1, @ids2)"

(如果“ids”中有3项)

答案 1 :(得分:3)

您需要用逗号分割sqlIn字符串,将每个字符串转换为整数,然后手动构建IN语句。

  string sqlIn = "1,2,3,4,5";
  string inParams = sqlIn.Split(',');
  List<string> paramNames = new List<string>();
  for(var i = 0; i < inParams.Length; ++i){
        string paramName = "@param" + i.ToString();
        SqlCeCommand cmd.Parameters.Add(paramName, SqlDbType.Int).Value = int.Parse(inParams[i]);
        paramNames.Add(paramName);
  }

  string sql = "... WHERE [personID] IN (" +
      string.Join(",", paramNames) +
      ") ...";