为什么 iif 中的子查询会影响结果?

问题描述 投票:0回答:1

3 个示例查询:

SELECT Pl_dscs.cid;
FROM itfwarehouse!pl_dscs;
INNER JOIN itfwarehouse!nonbaggedsys_descs ON Pl_dscs.cnonbaggedsys_descs_id = nonbaggedsys_descs.cid;
WHERE PL_dscs.cnonbaggedsys_descs_id = lcnbsdcid AND;
    iif(.f.,pl_dscs.ldiscontinued=.f.,.t.) AND;
    iif(.f.,.t.,.t.) INTO CURSOR lcresult

SELECT Pl_dscs.cid;
FROM itfwarehouse!pl_dscs;
INNER JOIN itfwarehouse!nonbaggedsys_descs ON Pl_dscs.cnonbaggedsys_descs_id = nonbaggedsys_descs.cid;
WHERE PL_dscs.cnonbaggedsys_descs_id = lcnbsdcid AND;
    iif(.f.,pl_dscs.ldiscontinued=.f.,.t.) AND;
    iif(.f.,.f.,.t.) INTO CURSOR lcresult

SELECT Pl_dscs.cid;
FROM itfwarehouse!pl_dscs;
INNER JOIN itfwarehouse!nonbaggedsys_descs ON Pl_dscs.cnonbaggedsys_descs_id = nonbaggedsys_descs.cid;
WHERE PL_dscs.cnonbaggedsys_descs_id = lcnbsdcid AND;
    iif(.f.,pl_dscs.ldiscontinued=.f.,.t.) AND;
    iif(.f.,NOT pl_dscs.cid in (select cpl_dscs_id FROM itfwarehouse!pl_dscsperfacwsite WHERE pl_dscsperfacwsite.cfacilities_id = ""),.t.) INTO CURSOR lcresult

这就是第二个示例和第三个示例之间的区别。

  • 第一个示例返回 1 条记录
  • 第二个示例返回 1 条记录
  • 第三个示例不返回任何记录

第二个和第三个示例之间的唯一区别是最后一个 iif 中的第二个表达式是子查询。由于该 iif 中的第一个表达式为 false,因此不应执行子查询。显然它在某种程度上影响了结果,但如何/为什么?

谢谢, 约翰

visual-foxpro
1个回答
0
投票

好的,我可以在我的工作机器上检查一下,我想你发现了一个错误。因为我们知道它永远不会得到纠正,所以这里有一个解决方法,不要使用 IIF(),而是使用模仿 IIF() 的表达式 - 无论如何,我从来不喜欢在 where 子句中使用 IIF() 的想法:

LOCAL llState
llState = .F.

SELECT Pl_dscs.cid;
FROM itfwarehouse!pl_dscs;
INNER JOIN itfwarehouse!nonbaggedsys_descs ON Pl_dscs.cnonbaggedsys_descs_id = nonbaggedsys_descs.cid;
WHERE PL_dscs.cnonbaggedsys_descs_id = lcnbsdcid AND;
    ((m.llState AND pl_dscs.ldiscontinued=.f.) OR (!m.llState AND .T.)) ;
    ((m.llState AND ;
        pl_dscs.cid NOT in ;
        (select cpl_dscs_id ;
        FROM itfwarehouse!pl_dscsperfacwsite ;
        WHERE pl_dscsperfacwsite.cfacilities_id = "");
    ) OR  (!m.llState AND .T.)) ;
INTO CURSOR lcresult ;
NOFILTER

根据错误本身的重现(和解决方法):

 LOCAL state
state = .F.

Select c.Cust_id, c.Country, o.Order_id ;
    FROM _samples+'data\Customer' c ;
    inner Join _samples+'data\Orders' o On c.cust_id = o.cust_id ;
    where c.Country = 'USA' And ;
    IIF(m.state, ;
        c.Cust_id NOT in (SELECT cust_id FROM _samples+'data\Customer' WHERE Country = 'USA' AND MaxOrdAmt > 1000) ;
        ,.T.) ; 
    ORDER BY c.Country, c.Cust_id, o.Order_id ;
    INTO Cursor crsResult ;
    nofilter


Select crsResult
Browse


Select c.Cust_id, c.Country, o.Order_id ;
    FROM _samples+'data\Customer' c ;
    inner Join _samples+'data\Orders' o On c.cust_id = o.cust_id ;
    where c.Country = 'USA' And ;
    ((m.state AND ;
        c.Cust_id NOT in (SELECT cust_id FROM _samples+'data\Customer' WHERE Country = 'USA' AND MaxOrdAmt > 1000)) ;
        OR ;
     (!m.state AND .T.)) ; 
    ORDER BY c.Country, c.Cust_id, o.Order_id ;
    INTO Cursor crsResult ;
    nofilter


Select crsResult
Browse

使用 IIF(),它是一种(但不准确)与子查询创建交叉连接。

© www.soinside.com 2019 - 2024. All rights reserved.