从第二个左连接突然“无效使用Null”

时间:2012-12-21 19:38:12

标签: sql ms-access-2007

我在Access中有这个SQL查询,工作正常:

SELECT TableA.FieldA As [Code],
   Count(TableA.FieldC) AS [Count]
FROM ((MainTable)
   LEFT JOIN TableA ON MainTable.FieldB = TableA.FieldB)
WHERE (((MainTable.DateOf)>=#1/1/2012#))
   AND Clng(TableA.FieldA) >= 119593451
   AND Clng(TableA.FieldA) <= 119593461
GROUP BY TableA.FieldA;

但是当我尝试另一个左连接时,就像这样:

SELECT TableA.FieldA As [Code],
   Count(TableA.FieldC) AS [Count]
FROM ((MainTable)
   LEFT JOIN TableA ON MainTable.FieldB = TableA.FieldB)
   LEFT JOIN TableB ON TableA.FieldD = TableB.FieldD
WHERE (((MainTable.DateOf)>=#1/1/2012#))
   AND Clng(TableA.FieldA) >= 119593451
   AND Clng(TableA.FieldA) <= 119593461
GROUP BY TableA.FieldA;

我在FROM claused中使用括号:http://nm1m.blogspot.com/2007/10/multiple-left-joins-in-ms-access.html

它给出了错误Invalid use of Null,这对我来说没有意义,因为我没有执行空检查等。这里有什么问题?我正在尝试拉出TableB中的一个字段来显示(但是还没有把它放在选择部分)。

1 个答案:

答案 0 :(得分:5)

Access喜欢它的括号。在连接周围添加更多括号。

CLng函数需要非空值。您可以使用CLng(Nz(TableA.FieldA, "0")) >= 119593451解决此问题。但是,如果该字段是数字的,那么为什么你会在文本中开始使用它?这是一个严重的问题,我强烈建议立即修改(如果可能的话)将数据类型更改为数字类型。

但是你有另一个问题。如果你在LEFT JOIN子句中提出一个条件,那么WHERE对于一个表是没有意义的,正如你在查询中所做的那样!可以更改为INNER JOIN或将TableA上的条件放入ON的{​​{1}}子句中。如果Access不允许此语法,则更改为派生表:

LEFT JOIN

注意:添加SELECT TableA.FieldA As [Code], Count(TableA.FieldC) AS [Count] FROM ( ( (MainTable) LEFT JOIN ( SELECT * FROM TableA WHERE Clng(Nz(TableA.FieldA, "0")) >= 119593451 AND Clng(Nz(TableA.FieldA, "0")) <= 119593461 ) TableA ON MainTable.FieldB = TableA.FieldB ) LEFT JOIN TableB ON TableA.FieldD = TableB.FieldD ) WHERE (((MainTable.DateOf)>=#1/1/2012#)) GROUP BY TableA.FieldA; 可能有效但可能无效。在Access中,它可以100%安全,但SQL Server中的此类查询不安全,因为无法保证应用条件的顺序。显然,在SQL Server中,即使在NULL且没有WHERE TableA.FieldA IS NOT NULL函数时也可以转换为整数,但这一点仍然有效:不要养成依赖CLng的某种想象顺序的习惯保护您免受无效类型转换的条件:相反,您必须处理可能出错的表达式中的无效类型转换 - 这是最佳做法。