Microsoft SQL Server 2008 (SP1), получая неожиданную ошибку «Ошибка преобразования».
Не совсем уверен, как описать эту проблему, поэтому ниже приведен простой пример. CTE извлекает числовую часть определенных идентификаторов, используя условие поиска, чтобы гарантировать, что числовая часть действительно существует. 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
);