【问题标题】:MS Access Data type mismatch in expression only in where statement仅在 where 语句中,表达式中的 MS Access 数据类型不匹配
【发布时间】:2013-02-15 18:43:55
【问题描述】:

我正在研究一个仅在 Where 语句中引发数据类型不匹配的表达式。

Current: IIf(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99)>0,
IIf(DateAdd("yyyy",CInt(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99))
,CVDate(Format(Nz([TEST_DATE],19891231),"0000-00-00")))>Now(),True,False),True)

如您所见,我为每个引用添加了一个Nz() 函数,甚至尝试在整个语句上强制转换CBool(),但它仍然会引发数据类型不匹配。

我已将其归结为该表达式,该表达式的工作方式与Select 语句中的预期完全一致。当我将它添加到Where 语句中,只希望返回True 时,就会发生错误。

我可能会错过什么?

更新:对感兴趣的人进行完整查询

SELECT Student.TECH_ID, Student.CAPP_LVL, Values.ABBR, Values.SHORT_DESC, Values.LONG_DESC, Values.GROUP_NBR, Values.NBR_YRS_VALID, Student.SEQ_NBR, Student.CAPP_LVL_SCORE, Student.TEST_DATE, IIf(Nz([Values].[NBR_YRS_VALID],99)>0,IIf(DateAdd("yyyy",CInt([Values].[NBR_YRS_VALID]),CVDate(Format([TEST_DATE],"0000-00-00")))>Now(),True,False),True) AS [Current], Values.END_DATE, Student.LOAD_DATE
FROM Student INNER JOIN Values ON Student.CAPP_LVL = Values.CAPP_LVL
WHERE (((Values.ABBR)<>"MTHB") AND ((Values.END_DATE) Like "9999*"))
ORDER BY Student.TECH_ID, Student.CAPP_LVL, Student.SEQ_NBR;

【问题讨论】:

  • 能否分享完整的查询?

标签: sql ms-access


【解决方案1】:

TEST_DATE 是什么数据类型和格式?如果我将其设为日期/时间数据类型并使数据评估为假,我会收到错误,但如果它评估为真,它会起作用。这可能就是您看到它在 Select 中工作的原因。当我将 TEST_DATE 设为双精度并在 nz 函数 (19981231) 中使用您的格式时,它适用于所有情况。

【讨论】:

  • 不得不破坏数据字典,哈哈。它是通过 ODBC 传入的 char 数据类型。我尝试在“TEST_DATE”上投射“CDbl()”,但没有任何运气。
  • 所以,我会仔细看看过来的数据。我可以通过对 TEST_DATE 数据使用不同的日期格式来复制错误。我确定您的错误是在 CVDate(更新的 VBA 函数是 CDate,但它们做同样的事情)函数中生成的,格式命令以某种方式扭曲了传入的日期之一,因此无法转换。
  • 你是对的。我隔离了 CVDate()(也更改为 CDate())并尝试在 where 语句中使用它并得到错误。现在的问题是如何解释这类问题。想法?
  • 例如,您的格式采用 '2/1/2012' 并将其转换为 0004-09-40,然后 CDate 将其解释为 4/9/1940。您甚至不需要格式,Access 足够聪明,可以(通常)以它们到达的格式解释日期。
  • 安迪,2 条建议追赶这个。由于这是作为 Char 出现的,我要做的第一件事是使用 IsNumeric 来查看是否有任何数据实际上不是数字,然后我会解析出前 4 位数字(Left(TEST_DATA,4) 并确保它们是在 1950 年到 2012 年之间。祝你好运。
【解决方案2】:

Where 语句看起来不像 Select 语句。 Access 需要一个 it 可以测试真假的条件表达式。

快速版本将采用整个语句并针对True 对其进行测试:

WHERE (IIf(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99)>0,
IIf(DateAdd("yyyy",CInt(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99))
,CVDate(Format(Nz([TEST_DATE],19891231),"0000-00-00")))>Now(),True,False),True))
= True

更好的解决方案是将其重写为由ANDOR 连接的几个不同的条件语句。我在解析它时遇到了问题,所以我不认为我会尝试这样做。

【讨论】:

    【解决方案3】:

    这对我有用:

    SELECT 
        IIf(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99)>0,IIf(DateAdd("yyyy",
           CInt(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99)),
           CVDate(Format(Nz([TEST_DATE],19891231),"0000-00-00")))
             >Now(),True,False),True) 
           AS [Current],
        ISRS_VAL_ST_CAPP_LVL.NBR_YRS_VALID, 
        ISRS_VAL_ST_CAPP_LVL.TEST_DATE
    FROM ISRS_VAL_ST_CAPP_LVL
    WHERE (((IIf(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99)>0,IIf(DateAdd("yyyy",
        CInt(Nz([ISRS_VAL_ST_CAPP_LVL].[NBR_YRS_VALID],99)),
        CVDate(Format(Nz([TEST_DATE],19891231),"0000-00-00")))
           >Now(),True,False),True))=true));
    

    NBR_YRS_VALID 和 TEST_DATE 都是长整数

    【讨论】:

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