2013-02-26 65 views
1

我有一個查詢,它的選擇基於日期字段。問題是這個日期字段有時是空的,所以僅僅使用'and not null'檢查null是行不通的。DateValue函數的標準表達式中的數據類型不匹配

這是我開發:

SELECT DISTINCT WS_ALL_OBJ.[Owner ID], Users.CHARGE_UNIT, WS_ALL_OBJ.[Owner Name] 
FROM WS_ALL_OBJ LEFT JOIN Users ON WS_ALL_OBJ.[Owner ID] = Users.CNAME 
WHERE 
    (IIF(IsNull(WS_ALL_OBJ.[Last Modified]), DateValue('2050-12-01'), DateValue(Left(WS_ALL_OBJ.[Last Modified], 10))) < #2012-11-26# 
    And 
    (Users.CHARGE_UNIT <> 'CQ')) 
GROUP BY WS_ALL_OBJ.[Owner ID], Users.CHARGE_UNIT, WS_ALL_OBJ.[Owner Name]; 

當運行這個查詢,它拋出一個「在正則表達式數據類型不匹配」的錯誤消息。

我已經縮小到這行代碼 - DateValue(Left(WS_ALL_OBJ.[Last Modified], 10)),因爲如果我用這個代替 - DateValue('2011-11-26') - 它工作得很好。

起初我還以爲是因爲有我Last Modified場這就是爲什麼我想出了這個空值 - (IIF(IsNull(WS_ALL_OBJ.[Last Modified]), DateValue('2050-12-01'), DateValue(Left(WS_ALL_OBJ.[Last Modified], 10))) < #2012-11-26#

難道不應該解決的空值的問題?

另一種可能性是來自Left()的字符串格式不正確。我認爲這是因爲這個 - DateValue('2011-11026') - (錯誤的格式)也會通過數據類型不匹配例外。

然而,這是所有的數據是什麼樣子:

2008-01-18 13:10:54 CST 

它存儲爲「文本」字段和來自鏈接的csv文件。功能Left()功能應採取前10個字符,並通過DateValue()

我很茫然,感謝任何幫助。

更新:我也試過cdate(Left(WS_ALL_OBJ.[Last Modified], 10))並得到相同的錯誤。 我也修改用來檢查`空字符串(ISNULL(WS_ALL_OBJ。[上次修改])或WS_ALL_OBJ。[上次修改] =「」)

我結束了在運行一些查詢只是爲了確保沒有WS_ALL_OBJ.[Last Modified] = ''或者存在WS_ALL_OBJ.[Last Modified] = ' '等。他們都返回了零結果。

我也嘗試了下面的建議查詢結構,但無濟於事。

+0

Last Modified的數據類型是什麼?如果它是一個字符串,它可以包含一個零長度的字符串。 – Tim 2013-02-26 15:38:59

+0

@Tim鍵入'Text' – hacket 2013-02-26 15:40:32

+0

也檢查零長度的字符串。 – Tim 2013-02-26 15:42:20

回答

1

考慮一個子查詢,以排除WS_ALL_OBJ行,其中[Last Modified]爲空。這樣可以避免在嘗試將空值轉換爲日期/時間值時發生的錯誤。

SELECT 
    w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name] 
FROM 
    (
     SELECT [Owner ID], [Owner Name], [Last Modified] 
     FROM WS_ALL_OBJ 
     WHERE [Last Modified] Is Not Null 
    ) AS w 
    LEFT JOIN Users AS u 
    ON w.[Owner ID] = u.CNAME 
WHERE 
     DateValue(Left(w.[Last Modified], 10)) < #2012-11-26# 
    AND u.CHARGE_UNIT <> 'CQ' 
GROUP BY w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name]; 

注:

  1. 我用別名爲表的名稱,因爲這使得SQL更容易爲我的大腦消化。
  2. 由於這是一個GROUP BY查詢,因此不需要DISTINCT
  3. WHERE子句條件(u.CHARGE_UNIT <> 'CQ')擊敗LEFT JOIN的目的。我不知道會發生什麼,但在我看來,您最好不要使用INNER JOIN
  4. 如果[Last Modified]也可含有零長度字符串,排除它們在子查詢WHERE

    WHERE LEN([上次修改])> 0

或者,也許只是使用IsDate()

WHERE IsDate([Last Modified]) = True 

或者......

WHERE IsDate(Left([Last Modified]), 10) = True 

順便說一句,您可能已經注意到,使用[Last Modified]作爲日期/時間而不是文本數據類型會更容易。我假設你出於某種原因被困在文本中。但是,如果沒有,請考慮改變它。

+0

我真的很喜歡你提出的格式。這是我以前嘗試過的,但我在SQL方面並不擅長。我使用了這種格式,並在子查詢中包含了WHERE Len([Last Modified])> 0,但它仍然返回'數據類型異常'問題。你也是對的,我正在開發一個我很遺傳的系統,它將日期字段轉換爲'日期',但它會導致更多的問題而不是解決。 – hacket 2013-02-26 16:20:47

+0

WS_ALL_OBJ是否包含其前10個[Last Modified]字符不代表有效日期的行?在我的頭頂,這是我明白爲什麼你仍然會得到這個錯誤的唯一原因。但那是「空碼」SQL。如果您提供一些數據,我可以根據樣本數據進行測試。 :-)另外,請注意我添加了一個關於'LEFT JOIN'的註釋。 – HansUp 2013-02-26 16:29:07

+0

我終於明白了。 Access在創建鏈接表時並未從數據中刪除「列標題」。所以最後修改='最後修改'在那裏有一排。我最終使用了你的解決方案,因爲我更喜歡它,並且爲這個不好的數據添加了一個檢查。多麼痛苦的屁股..感謝您的幫助。 – hacket 2013-02-26 17:28:00

0

下面是我通常如何處理這個問題。我冒昧地使用別名來縮短SQL並使其更具可讀性。我強烈建議不要在您的字段名稱中使用空格。如果你停止這種練習,你不必擔心使用括號。

我也猜測你正在將日期值存儲爲字符串。我通常儘量避免這種情況。我認爲在大多數情況下,最好是在需要時將日期值轉換爲字符串。

請確保您將vDate參數作爲變體數據類型保留在下面的函數中。如果您將其更改爲字符串或日期,則不會允許您處理空值。而不是得到錯誤你的SQL產生真正奇怪的結果。

你確定你的日期總是10個字符嗎?日期值可以表示而不引導零,這使得它們更短。

SELECT DISTINCT w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name] 
FROM WS_ALL_OBJ as w LEFT JOIN Users as u ON w.[Owner ID] = u.CNAME 
WHERE 
    GetLastModDate(w.[Last Modified]) < #2012-11-26# 
    And 
    u.CHARGE_UNIT <> 'CQ' 
GROUP BY w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name]; 


'Put this code in a VBA Module 
Public Function GetLastModDate(vDate) as Date 
    If Nz(vDate, "") = "" Then 
     GetLastModDate = #01/12/2050# 
    Else 
     GetLastModDate = DateValue(Left(vDate), 10) 
     End If 
End Function 
相關問題