2017-09-21 81 views
0

所以我有這樣的代碼運行偉大:日期列將不轉換where子句

SELECT 
    QuoteDet.QuoteNo, 
    Quote.SalesID, 
    Quote.CustCode, 
    QuoteDet.PartNo AS [Version], 
    QuoteDet.Price1 AS [Unit Price], 
    CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) AS [Submittal Date] 
FROM QuoteDet INNER JOIN Quote ON QuoteDet.QuoteNo = Quote.QuoteNo 
WHERE QuoteDet.Status IN ('Req', 'Pend') 
AND QuoteDet.User_Text1 <> 'HOLD' 
GROUP BY QuoteDet.QuoteNo, Quote.SalesID, Quote.CustCode, QuoteDet.PartNo, 
QuoteDet.Price1, QuoteDet.User_Text1 
ORDER BY CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) 

但是,當我在where子句中添加以下條件來得到當前一週,我得到的消息從字符串轉換日期或時間「轉換失敗

SELECT 
    QuoteDet.QuoteNo, 
    Quote.SalesID, 
    Quote.CustCode, 
    QuoteDet.PartNo AS [Version], 
    QuoteDet.Price1 AS [Unit Price], 
    CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) AS [Submittal Date] 
FROM QuoteDet INNER JOIN Quote ON QuoteDet.QuoteNo = Quote.QuoteNo 
WHERE QuoteDet.Status IN ('Req', 'Pend') 
AND CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) >= 
DATEADD(DAY, 1-DATEPART(dw, GETDATE()), CONVERT(DATE, GETDATE())) 
AND CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) < 
DATEADD(DAY, 8-DATEPART(dw, GETDATE()), CONVERT(DATE, GETDATE())) 
AND QuoteDet.User_Text1 <> 'HOLD' 
GROUP BY QuoteDet.QuoteNo, Quote.SalesID, Quote.CustCode, QuoteDet.PartNo, 
QuoteDet.Price1, QuoteDet.User_Text1 
ORDER BY CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) 

爲什麼我沒有拿到第一個查詢錯誤?它也轉換爲日期,但沒有錯誤

+0

提示:'GetDate()'在查詢中有點奇怪。每個_instance_在查詢中都有一個常量值。例如'select D1(GetDate(),GetDate()as SomeTable'中的D2可能爲兩列返回兩個不同的值,但它們不會因行而變化。當在多個語句中使用'GetDate()'時,例如在存儲過程中,可以通過獲取單個值並在整個過程中使用它,即'declare @Now as DateTime = GetDate();'並根據需要使用'@ Now'來避免有趣的意外。 – HABO

回答

1

另一種可能性,第一查詢的工作,因爲SELECT子句中轉換行的縮小後會發生由where子句。通過將convert轉換爲where子句,它現在可以在所有行上運行,其中一些行可能有不良數據,無法通過第一個查詢中的select子句。

如果您對SQL Server的足夠新的版本,TRY_PARSE將通過非可轉換字符串返回NULL允許沒有錯誤的轉換。

+0

TRY_PARSE令人驚歎,謝謝。仍然不知道爲什麼我的原始代碼失敗。我嘗試了CONVERT(CAST())和CAST()的每個組合。兩者都無效,但TRY_PARSE的作用像一個魅力 –

+0

@CristianContreras由於匿名生產代碼,這可能是一個錯誤。在第二個查詢中,您有'QuoteDet.User_Text1 <>'HOLD''和'CAST(QuoteDet.User_Text1 AS DATE)'。 'QuoteDet.User_Text1'爲_HOLD_的任何行都將使演員失敗到一個日期。 –

+0

是的,我確定暫停是問題,只是不確定爲什麼第一個查詢能夠轉換沒有問題。我想這與查詢執行的順序有關 –

1

在第一個查詢你:

  • 第一投射了「QuoteDet.User_Text1」作爲一個日期
  • 然後將結果轉換爲VARCHAR長度30,產生一個字符串

在你的第二個查詢,您正嘗試使用字符串來檢查日期。你應該在WHERE子句中做的是除去'Convert'方法調用,並使用'Cast'方法。因此,而不是這樣的:

CONVERT(VARCHAR(30), CAST(QuoteDet.User_Text1 AS DATE), 1) 

你必須使用你的WHERE子句中的以下內容:

CAST(QuoteDet.User_Text1 AS DATE) 
+0

但是然後我的第一個查詢也無法正常工作,但是那個能夠無誤地轉換。我只嘗試過使用CAST。同樣的問題,第一個查詢工作,第二個不是。不知道爲什麼在WHERE子句中使用該列會導致代碼崩潰 –

+1

@CristianContreras,還有一個隱含的從varchar轉換回到where子句中進行比較的日期。這在select子句中沒有發生。 –

+0

在第一個查詢中,您使用CONVERT(VARCHAR(30),CAST(QuoteDet.User_Text1 AS DATE),1)顯示一個值。在where子句中,您需要將該值與其他日期進行比較。這就是爲什麼它在第一個查詢中工作。 –