Conversion перестал работать, когда преобразование varchar оценивает интервалу

Microsoft SQL Server 2008 (SP1), получая неожиданного 'Conversion привел к сбою' ошибку.

Не совсем уверенный, как описать эту проблему, таким образом, ниже простой пример. 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
                  );

Ошибка, 'Conversion перестал работать, когда преобразование varchar оценивает 'RR' интервалу типа данных'.

Я не могу понять почему значение 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
                  );

Почему базовая таблица вызвала бы эту ошибку? Действительно ли это - известная проблема?


ОБНОВЛЕНИЕ @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
                  );
8
задан onedaywhen 4 May 2010 в 12:12
поделиться

2 ответа

Это ошибка, о которой уже сообщалось как SQL Server не должен вызывать нелогичные ошибки (как я уже сказал, это сложно описать один!) Эрланда Соммарского.

Ответ от группы программирования SQL Server: «Проблема в том, что SQL Server выдает ошибки [слишком] из-за проталкивания предиатов / выражений во время выполнения запроса без учета логического результата запроса».

I проголосовали за исправление, все сделайте то же самое, пожалуйста :)

4
ответ дан 6 December 2019 в 00:05
поделиться

Что делать, если вы замените раздел

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
ответ дан 6 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: