WHERE子句中的嵌套括号

时间:2018-10-18 20:03:51

标签: sql where-clause parentheses

我一直在修改此查询的括号,但无济于事。有人可以指出可能导致错误的特定地点吗?这是错误消息:

enter image description here

以下是查询:

SELECT 
tExceptionsAll1.ID, 
tExceptionsAll1.CardholderName, 
PCARDS_ILL_DBO_CARD.PERSON_ID, 
tExceptionsAll1.CardType, 
tExceptionsAll1.Duration, 
tExceptionsAll1.ExceptionType, 
tExceptionsAll1.STL AS [Exp STL], 
tExceptionsAll1.CL AS [Exp CL], 
PCARDS_ILL_DBO_CARD.TRANS_LIMIT_AMT AS [Card STL], 
PCARDS_ILL_DBO_CARD.MONTH_LIMIT_AMT AS [Card CL], 
tExceptionsAll1.TerminationDate, 
tExceptionsAll1.DCMNames, 
tExceptionsAll1.ReminderDate
FROM PCARDS_ILL_DBO_CARD 
INNER JOIN tExceptionsAll1 ON (PCARDS_ILL_DBO_CARD.CARD_ID = CLNG(tExceptionsAll1.CardID)) 
      AND (CLNG(PCARDS_ILL_DBO_CARD.PERSON_ID) = tExceptionsAll1.CardholderUIN)
WHERE (
  ((tExceptionsAll1.STL)>0) 
  And ((tExceptionsAll1.CL)>0) 
  And ((PCARDS_ILL_DBO_CARD.TRANS_LIMIT_AMT)<>tExceptionsAll1.STL) 
  And ((PCARDS_ILL_DBO_CARD.MONTH_LIMIT_AMT)<>tExceptionsAll1.CL) 
  And ((tExceptionsAll1.TerminationDate) Is Null)
) 
OR (
  ((tExceptionsAll1.TempSTL)>0) 
  And ((tExceptionsAll1.TempCL)>0) 
  And ((PCARDS_ILL_DBO_CARD.TRANS_LIMIT_AMT)<>tExceptionsAll1.TempSTL) 
  And ((PCARDS_ILL_DBO_CARD.MONTH_LIMIT_AMT)<>tExceptionsAll1.TempCL) 
  And ((tExceptionsAll1.TerminationDate) Is Null) 
  And ((tExceptionsAll1.ReminderDate) < getdate())
);

1 个答案:

答案 0 :(得分:1)

tl; dr:Access has no getdate function


但是让我们更容易阅读该查询。

扩大查询范围可以使跟踪变得更加容易。

SELECT
    tExceptionsAll1.ID,
    tExceptionsAll1.CardholderName,
    PCARDS_ILL_DBO_CARD.PERSON_ID,
    tExceptionsAll1.CardType, 
    tExceptionsAll1.Duration,
    tExceptionsAll1.ExceptionType,
    tExceptionsAll1.STL AS [Exp STL],
    tExceptionsAll1.CL AS [Exp CL], 
    PCARDS_ILL_DBO_CARD.TRANS_LIMIT_AMT AS [Card STL],
    PCARDS_ILL_DBO_CARD.MONTH_LIMIT_AMT AS [Card CL], 
    tExceptionsAll1.TerminationDate,
    tExceptionsAll1.DCMNames,
    tExceptionsAll1.ReminderDate
FROM PCARDS_ILL_DBO_CARD
INNER JOIN tExceptionsAll1 
    ON (PCARDS_ILL_DBO_CARD.CARD_ID = CLNG(tExceptionsAll1.CardID)) AND
       (CLNG(PCARDS_ILL_DBO_CARD.PERSON_ID) = tExceptionsAll1.CardholderUIN)
WHERE (
    ((tExceptionsAll1.STL)>0) And
    ((tExceptionsAll1.CL)>0) And
    ((PCARDS_ILL_DBO_CARD.TRANS_LIMIT_AMT)<>tExceptionsAll1.STL) And
    ((PCARDS_ILL_DBO_CARD.MONTH_LIMIT_AMT)<>tExceptionsAll1.CL) And
    ((tExceptionsAll1.TerminationDate) Is Null)
)
    OR 
(
    ((tExceptionsAll1.TempSTL)>0) And
    ((tExceptionsAll1.TempCL)>0) And
    ((PCARDS_ILL_DBO_CARD.TRANS_LIMIT_AMT)<>tExceptionsAll1.TempSTL) And
    ((PCARDS_ILL_DBO_CARD.MONTH_LIMIT_AMT)<>tExceptionsAll1.TempCL) And
    ((tExceptionsAll1.TerminationDate) Is Null) And
    ((tExceptionsAll1.ReminderDate) < getdate())
);

一个好的文本编辑器,例如Atom将为您匹配parens。它们似乎都可以平衡。

虽然可以使用括号将or这样的优先级问题明确化,但太多的问题只会使事情变得棘手。无需在每次比较时都加上括号。让我们剥离一些。我们还对表进行别名化以消除冗余。

SELECT
    tea1.ID,
    tea1.CardholderName,
    pidc.PERSON_ID,
    tea1.CardType, 
    tea1.Duration,
    tea1.ExceptionType,
    tea1.STL AS [Exp STL],
    tea1.CL AS [Exp CL], 
    pidc.TRANS_LIMIT_AMT AS [Card STL],
    pidc.MONTH_LIMIT_AMT AS [Card CL], 
    tea1.TerminationDate,
    tea1.DCMNames,
    tea1.ReminderDate
FROM pidc
INNER JOIN tea1 
    ON pidc.CARD_ID = CLNG(tea1.CardID) AND
       CLNG(pidc.PERSON_ID) = tea1.CardholderUIN
WHERE (
    tea1.STL > 0 AND
    tea1.CL  > 0 AND
    pidc.TRANS_LIMIT_AMT <> tea1.STL AND
    pidc.MONTH_LIMIT_AMT <> tea1.CL  AND
    tea1.TerminationDate IS NULL
)
    OR 
(
    tea1.TempSTL > 0 AND
    tea1.TempCL  > 0 AND
    pidc.TRANS_LIMIT_AMT <> tea1.TempSTL AND
    pidc.MONTH_LIMIT_AMT <> tea1.TempCL AND
    tea1.TerminationDate IS NULL AND
    tea1.ReminderDate < getdate()
);

您可能会提出比我更好的表别名。

您的错误是Wrong number of arguments used with function in query expression。既然所有内容都已间隔开,我们可以看到只有两个函数调用:getdate()CLNG()CLNG is an Access fuctiongetdate() is not!相反,我们应该使用date()