【问题标题】:Unexpected cartesian product in Foxpro SQL statementFoxpro SQL 语句中出现意外的笛卡尔积
【发布时间】:2016-04-21 21:18:05
【问题描述】:

我正在从 C# 程序执行以下 Visual FoxPro SQL 语句。我希望得到 1 个结果,但我没有得到任何结果。

SELECT 
    iplclaim.lc_lname, ipcname.cn_lname, ipcbusn.cb_bname   ;
FROM 
    iplclaim  ;
INNER JOIN 
    iplclsub ON iplclsub.ls_claimno + iplclsub.ls_sclaimno = iplclaim.lc_claimno + 'A' ;
LEFT OUTER JOIN 
    ipcname ON ipcname.cn_inqno = iplclsub.ls_inqno  ;
LEFT OUTER JOIN 
    ipcbusn ON ipcbusn.cb_inqno = iplclsub.ls_inqno  ;
WHERE 
    iplclaim.lc_claimno = '  1105'     ;
    AND NOT DELETED() 

我能够使用以下程序重现从 VFP 运行的问题...

CLOSE DATABASES all
OPEN DATABASE ipcust.dbc
USE C:\TESTVFP\IPS\DATA\PPDATA\IPlclaim IN 0
USE C:\TESTVFP\IPS\DATA\PPDATA\iplclsub IN 0
USE C:\TESTVFP\IPS\DATA\PPDATA\IPcname IN 0
USE C:\TESTVFP\IPS\DATA\PPDATA\IPcbusn IN 0
SYS(3054,12)

SELECT iplclaim.lc_lname, ipcname.cn_lname, ipcbusn.cb_bname   ;
 FROM iplclaim  ;
INNER JOIN iplclsub ON iplclsub.ls_claimno + iplclsub.ls_sclaimno = '  1105A'     ;
 LEFT OUTER JOIN ipcname ON ipcname.cn_inqno = iplclsub.ls_inqno  ;
 LEFT OUTER JOIN ipcbusn ON ipcbusn.cb_inqno = iplclsub.ls_inqno  ;
WHERE iplclaim.lc_claimno = '  1105' ;
  AND NOT DELETED() 

似乎如果在程序执行之前没有打开表,结果是零记录。如果我打开表并只执行 SQL 语句,它会返回预期的一条记录。

另一件我没想到的是,当我运行上面的程序时,SYS(3054,12) 返回以下结果(注意“笛卡尔积”)...

SELECT ipcname.cn_lname, ipcbusn.cb_bname FROM iplclsub LEFT OUTER JOIN ipcname ON ipcname.cn_inqno = iplclsub.ls_inqno LEFT OUTER JOIN ipcbusn ON ipcbusn.cb_inqno = iplclsub.ls_inqno WHERE  iplclsub.ls_claimno + iplclsub.ls_sclaimno = '  1105A' AND NOT ip
Using index tag Claimall to rushmore optimize table iplclsub
Rushmore optimization level for table iplclsub: partial
Rushmore optimization level for table ipcname: none
Rushmore optimization level for table ipcbusn: none
Joining table iplclsub and table ipcname (Cartesian product)
Joining intermediate result and table ipcbusn (Cartesian product)

但是当我在表已经打开的情况下自行运行 SQL 语句时,输出看起来不同(注意没有“Cartisian product”)

SELECT ipcname.cn_lname, ipcbusn.cb_bname FROM iplclsub LEFT OUTER JOIN ipcname ON ipcname.cn_inqno = iplclsub.ls_inqno LEFT OUTER JOIN ipcbusn ON ipcbusn.cb_inqno = iplclsub.ls_inqno WHERE  iplclsub.ls_claimno + iplclsub.ls_sclaimno = '  1105A' AND NOT ip
Using index tag Claimall to rushmore optimize table iplclsub
Rushmore optimization level for table iplclsub: partial
Rushmore optimization level for table ipcname: none
Rushmore optimization level for table ipcbusn: none
Joining table iplclsub and table ipcname using tag Inqno
Joining intermediate result and table ipcbusn using tag Inqno

最后说明: iplclaim 中只有一条记录与WHERE 子句匹配。 iplclsub 中只有一条记录与INNER JOIN iplclsub ON 子句匹配。 ipcname 中只有一条记录匹配LEFT OUTER JOIN ipcname ON 子句,ipcbusn 中没有记录匹配LEFT OUTER JOIN ipbusn ON 子句。

谁能解释导致这个问题的原因以及我必须做些什么来解决它?

编辑:

好吧,我发现问题出在AND NOT DELETED()。如果我删除该子句,一切都会按预期进行。谁能解释一下,谁能告诉我另一种排除已删除记录的方法?

【问题讨论】:

    标签: sql visual-foxpro


    【解决方案1】:

    FoxPro 文档中有一条警告,当在多个表查询中使用 DELETED() 等函数时,SELECT-SQL 命令可能会返回意外结果。

    SET DELETED ON 命令可用于忽略标记为删除的记录。启用该选项后,似乎可以从查询中删除 DELETED() 函数的使用。

    对于 C# 代码,假设您使用的是 OLEDB 连接,则可以在执行查询之前在同一个打开的 FoxPro 连接上执行 SET DELETED ON 命令。

    【讨论】:

      猜你喜欢
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多