Функция STR()
принимает тип данных с плавающей точкой в качестве первого аргумента, поэтому SQL Server неявно преобразует все, что вы передаете этой функции, которая в вашем случае является столбцом CHAR(20)
. Поскольку unknown
не может быть преобразовано в число с плавающей точкой, вы получите ошибку.
Если вы запустите следующее с активным планом выполнения:
DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL);
SELECT Result = ISNULL(STR(Col, 25, 0), 'Missing')
FROM @T
Затем проверьте план выполнения XML и увидите неявное преобразование:
<ScalarOperator ScalarString="isnull(str(CONVERT_IMPLICIT(float(53),[Col],0),(25),(0)),'Missing')">
Самое простое решение, вероятно, состоит в том, чтобы использовать выражение case и вообще не беспокоиться о каком-либо преобразовании (только если вы знаете, что у вас будут только 5 значений, перечисленных вами:
DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL), ('0'), ('50'), ('100');--, ('Unknown');
SELECT Result = CASE WHEN Col IS NULL OR Col = 'Unknown' THEN 'Missing' ELSE Col END
FROM @T;
Result
---------
Missing
0
50
100
Missing
Если вам действительно нужна функция STR()
, вы можете сделать преобразование явным, но используйте TRY_CONVERT()
, чтобы все, что не является плавающей точкой, просто возвращало NULL
:
DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL), ('0'), ('50'), ('100');--, ('Unknown');
SELECT Result = ISNULL(STR(TRY_CONVERT(FLOAT, Col), 25, 0), 'Missing')
FROM @T
Result
------------
Missing
0
50
100
Missing
Хотя, поскольку указанные вами числа являются целыми числами, я был бы склонен преобразовывать их в целые числа, а не в числа с плавающей точкой:
DECLARE @T TABLE (Col CHAR(20));
INSERT @T VALUES (NULL), ('0'), ('50'), ('100'), ('Unknown');
SELECT Result = ISNULL(CONVERT(VARCHAR(10), TRY_CONVERT(INT, Col)), 'Missing')
FROM @T;
Result
---------
Missing
0
50
100
Missing