2010-05-04 254 views
7

Microsoft SQL Server 2008(SP1),出現意外的「轉換失敗」錯誤。將varchar值轉換爲int時出現轉換失敗

不太清楚如何描述這個問題,所以下面是一個簡單的例子。 CTE使用搜索條件提取某些ID的數字部分,以確保數字部分實際存在。然後,CTE被用於找到(種)的最​​低未使用的序列號:

CREATE TABLE IDs (ID CHAR(3) NOT NULL UNIQUE); 

INSERT INTO IDs (ID) VALUES ('A01'), ('A02'), ('A04'), ('ERR'); 

WITH ValidIDs (ID, seq) 
AS 
(
SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
    FROM IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 
) 
SELECT MIN(V1.seq) + 1 AS next_seq 
    FROM ValidIDs AS V1 
WHERE NOT EXISTS (
        SELECT * 
        FROM ValidIDs AS V2 
        WHERE V2.seq = V1.seq + 1 
       ); 

該錯誤是,RR「轉換VARCHAR值時,轉換失敗‘’爲int數據類型」。

我不明白爲什麼值ID = 'ERR'應該考慮轉換,因爲謂詞ID LIKE 'A[0-9][0-9]'應該已經從結果集中刪除了無效行。

當基臺取代有一個等效CTE問題消失即

WITH IDs (ID) 
AS 
(
SELECT 'A01' 
UNION ALL 
SELECT 'A02' 
UNION ALL 
SELECT 'A04' 
UNION ALL 
SELECT 'ERR' 
), 
ValidIDs (ID, seq) 
AS 
(
SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
    FROM IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 
) 
SELECT MIN(V1.seq) + 1 AS next_seq 
    FROM ValidIDs AS V1 
WHERE NOT EXISTS (
        SELECT * 
        FROM ValidIDs AS V2 
        WHERE V2.seq = V1.seq + 1 
       ); 

爲什麼一個基本表引起該錯誤?這是一個已知的問題?


UPDATE @sgmoore:無,做在一個CTE過濾並且在另一個CTE鑄造仍然會導致相同的錯誤例如

WITH FilteredIDs (ID) 
AS 
(
SELECT ID 
    FROM IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 

), 
ValidIDs (ID, seq) 
AS 
(
SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
    FROM FilteredIDs 
) 
SELECT MIN(V1.seq) + 1 AS next_seq 
    FROM ValidIDs AS V1 
WHERE NOT EXISTS (
        SELECT * 
        FROM ValidIDs AS V2 
        WHERE V2.seq = V1.seq + 1 
       ); 
+1

核心CTE工作正常 - 通過使用「SELECT * FROM ValidIDs」而不是您的查詢來嘗試它。錯誤必須在其他地方... – 2010-05-04 11:21:03

+0

@marc_s:我同意CTE不是問題的根源。我不確定CTE是如何工作的,但我希望CTE的查詢只是在解析時擴展到查詢中。事實上,使用兩個派生表(當然,每個語法都完全相同)重寫查詢仍然會出現問題。 – onedaywhen 2010-05-04 11:35:08

回答

3

這是一個錯誤,已經被報告爲SQL Server should not raise illogical errors(正如我所說,這是很難形容這一個! )通過Erland Sommarskog。

來自SQL Server可編程團隊的迴應是,「問題在於SQL Server由於在查詢執行過程中推送推理/表達式而不考慮查詢的邏輯結果而急切地引發錯誤。

現在我已經投了一個解決方法,大家都做同樣的請:)

+0

也可以在這個Q中看到甲骨文。https://stackoverflow.com/q/46287236/73226 – 2017-09-18 20:11:10

0

更換什麼,如果部分

SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
FROM IDs 
WHERE ID LIKE 'A[0-9][0-9]' 

隨着

SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
FROM 
(
    select ID from IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 
) 
+0

我得到同樣的錯誤。看到我的編輯問題。 – onedaywhen 2010-05-04 12:14:39

+0

很奇怪,不,我不明白。該錯誤似乎是在哪裏V2.seq = V1.seq + 1 將其更改爲 WHERE isnumeric(v2.seq)= 1且isnumeric(v1.seq)= 1且V2.seq = V1。 seq + 1 作品(對我而言) – sgmoore 2010-05-04 12:47:09

0

這發生在我身上,因爲我做了一個聯盟,是不小心,以確保這兩個查詢了各自領域以相同的順序。一旦我解決了這個問題,那就很好。

相關問題