[英]Conversion failed when converting the varchar value to int
Microsoft SQL Server 2008(SP1),遇到意外的“轉換失敗”錯誤。
不太確定如何描述此問題,因此下面是一個簡單的示例。 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
);
錯誤為“將varchar值RR轉換為數據類型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
);
這是一個錯誤,並且已經被報告為SQL Server不應引發不合邏輯的錯誤 (正如我所說,很難描述這一錯誤!)。
SQL Server可編程性團隊的回答是:“問題在於,SQL Server急於在執行查詢過程中推送謂詞/表達式,而又不考慮查詢的邏輯結果,從而[引發]錯誤。”
我現在已投票決定要解決的問題,每個人都請這樣做:)
這發生在我身上,是因為我做了一個Union,並且不小心確保兩個查詢的字段順序都相同。 一旦我解決了,那就很好了。
如果替換該部分該怎么辦
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]'
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.