为什么OLEDB(或Access?)重写WHERE子句

时间:2016-10-26 12:49:09

标签: sql ms-access ado.net oledb

我正面临一种奇怪的情况:OledbDataAdapter重新排列查询的WHERE子句,从而改组所有参数。此外,它无法识别查询中使用的参数之一。这是怎么回事:

一个包含4列(和无限行:)的简单表格):

Name       varchar(50)
Category   varchar(20)  //One of around 15-20 possible values
YR         int          //Year
Period     int          //Month

用户将使用Year,Month和他感兴趣的以逗号分隔的类别列表来查询此表。由于.NET不支持通过IN运算符的多值参数,我所做的就是接受以逗号分隔列表的类别列表,然后在查询中为此列表添加逗号并附加逗号,并使用内置INSTR()函数过滤所需类别的结果。用户还可以为类别过滤器提供空字符串,在这种情况下,查询将需要返回所有结果(即不对类别进行过滤)。

因此我的查询如下所示:

SELECT * FROM [Table1] WHERE
       YR = ? AND 
       Period = ? AND 
       (LTRIM(RTRIM(?)) = '' OR INSTR(1, ?, ',' + Category + ',') > 0)

过去,这与多边开发银行合作。但最近我尝试对抗ACCDB。我注意到的第一件事是,当我尝试在OledbDataAdapter向导中运行查询时,Visual Studio将其重写为:

SELECT * FROM [Table1] WHERE
       (YR = ? AND Period = ? AND LTRIM(RTRIM(?)) = '') OR 
       (YR = ? AND Period = ? AND INSTR(1, ?, ',' + Category + ',') > 0)

换句话说,它已将条件A AND B AND (C OR D)重新排列为(A AND B AND C) OR (A AND B AND D)

这对我来说没问题,但另外一个问题是这会将参数数量从4改为6;因此,即使应该查询,查询也不会返回任何结果。而且,它根本不识别最后一个参数(INSTR函数中的问号)。

所以我的问题是:

  1. 谁在重写查询(OledbDataAdapter,访问查询解析器或其他什么内容?)
  2. 为什么这样做?优化?显然我的WHERE子句版本效率更高。
  3. 为什么不看最后一个参数?
  4. 如何修复/解决此问题? (PLZ不建议使用2个单独的查询)。

0 个答案:

没有答案