【问题标题】:IN Operator in OLEDBOLEDB 中的 IN 运算符
【发布时间】:2017-10-18 09:12:37
【问题描述】:

我正在使用 OLEDB 连接从 excel 文件中读取数据。在 Select 查询中使用 IN 运算符时遇到问题。 以下是我的查询,

string EmployeeIds = "'1231','1232','1233'";
SELECT [Employee Number],[Employee Name],[First In Time],[Last Out Time],[Total Work Hours] 
FROM [Sheet0$A2:J] 
WHERE  [Employee Number] IN (?);

 comm.Parameters.AddWithValue("?",EmployeeIds);

我得到空结果,但如果我只给出一个值,那么我得到的结果。请帮忙。

【问题讨论】:

    标签: c# asp.net oledb


    【解决方案1】:
    where someval in ('123,456,789')
    

    非常不同

    where someval in (123,456,789)
    

    第二行针对 3 个数值测试 someval;第一行测试someval针对恰好包含数字和逗号的单个字符串值(但这些数字和逗号无关)。

    如果没有(其中之一),您将无法做您想做的事:

    • 动态编写 SQL 以使每个值有一个参数,即in (?,?,?,?)
    • 利用后端的某些功能进行拆分 - 例如在 SQL Server 最新版本中的STRING_SPLIT(这将是非常特定于后端的);我对 Excel 的了解不够,无法就是否存在这样的功能提出建议

    【讨论】:

      【解决方案2】:

      这是一个非常常见的错误。
      IN 运算符需要一个值列表,但您提供的单个值恰好包含一个列表。 您应该为 EmployeeIds 列表中的每个值创建不同的参数。

      这是一种方法:

      string EmployeeIds = "'1231','1232','1233'";
      var values = EmployeeIds.Split(',');
      
      using(var command = new OleDbCommand())
      {
          var sql = "SELECT [Employee Number], [Employee Name], [First In Time], [Last Out Time], [Total Work Hours] "+
                    "FROM [Sheet0$A2:J] "+
                    "WHERE [Employee Number] IN (";
      
          for(int i=0; i < values.Length; i++) 
          {
              // Please note that string interpolation will work only with c# 6 or later.
              // If you are working with vs 2013 or earlier, use string.Format instead.
              sql = $"{sql} @{i},";
              command.Parameters.Add($"@{i}", OleDbType.Int).Value = values[i].Trim(new char[] {'}); // You don't need the ' anymore since you are working with parameters now...
          }
      
          command.CommandText = sql.TrimEnd(',') +");";
          command.Connection = con;
          using(var reader = Command.ExecuteReader())
          {
              while(reader.Read())
              {
                  // do your stuff with the data
              }
      
          }
      }
      

      【讨论】:

      • 一些改进:使用列表来存储参数占位符(它们应该是“?”,因为我们不知道底层数据库)并仅使用字符串构建最终查询。加入而不是许多字符串操作(有很多参数可能是性能问题),参数也是 OleDb.Int32 类型,但操作使用字符串。这取决于引擎是否可行。最好做正确的事情并转换它们
      • @Steve 你的意思是像your answer here?我实际上考虑过,但认为这将是一种抄袭,虽然这是最真诚的奉承形式,但我认为我最好在应得的地方留下信用:-)
      • 啊,原来是这样。也许我们应该将其作为重复项关闭,但这是不可能的。很确定周围还有其他重复项
      • 是的,你可能是对的,however....
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-18
      • 2011-11-15
      • 2012-05-10
      • 2019-11-02
      • 1970-01-01
      相关资源
      最近更新 更多