SQL Server: Ошибка при преобразовании типа данных nvarchar в числовой в зависимости от используемого условия WHERE - PullRequest
0 голосов
/ 24 января 2019

Я работаю с таблицей, в которой есть столбец NVARCHAR ID и еще два столбца NVARCHAR, которые имеют только десятичные значения, но я не могу изменять схему.

Используя CAST(FIELD AS DECIMAL(18,6)), я могу выполнить необходимые вычисления для данных при запросе одного идентификатора, но я получаю ошибку преобразования при запросе 2 идентификаторов.

Рассмотрим два идентификатора, 'TEST1 'и AND TEST2', следующее будет работать нормально

SELECT ID, CAST(FIELD AS DECIMAL(18,6)) AS FOO 
FROM MY_TABLE 
WHERE ID = 'TEST1'

Это также будет работать нормально

SELECT ID, CAST(FIELD AS DECIMAL(18,6)) AS FOO 
FROM MY_TABLE 
WHERE ID = 'TEST2'

Это, однако, приведет к ошибке

Ошибка преобразования типа данных nvarchar в числовой

SELECT ID, CAST(FIELD AS DECIMAL(18,6)) AS FOO 
FROM MY_TABLE 
WHERE ID = 'TEST1' OR ID = 'TEST2'

Как мне справиться с этим?

1 Ответ

0 голосов
/ 24 января 2019

Разница заключается в пути выполнения.Исходя из ваших первых двух запросов, следующие должны возвращать действительный набор результатов:

SELECT ID, CAST(FIELD AS DECIMAL(18,6)) AS FOO
FROM MY_TABLE
WHERE ID = 'TEST1' OR ID = 'TEST2';

К сожалению, происходит то, что SQL Server решает выполнить полное сканирование таблицы и pushcast() ближе к данным.Некоторое значение FIELD, отличное от 'TEST1' или 'TEST2', вызывает проблему.

Я считаю это ошибкой.Независимо от моего мнения, в SQL Server 2012 + есть простое исправление:

SELECT ID, TRY_CAST(FIELD AS DECIMAL(18, 6)) AS FOO
FROM MY_TABLE
WHERE ID = 'TEST1' OR ID = 'TEST2';

В SQL Server 2008 (который скоро больше не будет поддерживаться) можно использовать выражение CASE:

SELECT ID,
       (CASE WHEN FIELD NOT LIKE '%[^0-9.]%' AND
                  FIELD NOT LIKE '%.%.%'
             THEN CAST(FIELD AS DECIMAL(18, 6))
        END) AS FOO
FROM MY_TABLE
WHERE ID = 'TEST1' OR ID = 'TEST2';

Вместо сбоя возвращается NULL, который просто игнорируется.Также вы должны использовать ID IN ('TEST1', 'TEST2') вместо OR, но это не имеет отношения к вашему вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...