Здесь есть две основные проблемы.
Первое - найти функцию, которая будет всесторонне определять, действительно ли значение в вашем столбце NVARCHAR представляет собой число. Во-вторых, убедитесь, что элемент THEN оператора CASE не оценивает, когда ему это не нужно.
Как вы заметили, встроенная функция TRANSLATE может выполнять достойную работу, но она не является надежной. Насколько я знаю, нет встроенной функции, которая может надежно выполнить эту проверку.
Однако есть два включенных UDF, которые хорошо справятся с этой задачей. Администратор должен явно активировать обе эти функции.
- ISNUMBER, в комплекте с функциями Инза
- REGEXP_LIKE, в комплекте с SQL-расширение Toolkit
Ниже приведены примеры с использованием как, показывающие оттенок SMALLINT. В каждом я поставил тестовый CASE в подзапрос, чтобы гарантировать, что конечный CAST не изолирован от исходного значения. Вы можете подумать, что вы можете это кодировать только в двух вложенных CASE, но с UDF вы не всегда можете положиться на это поведение.
ISNUMBER образец:
SELECT ORIG_COL,
CASE
WHEN COL1 BETWEEN -32678 AND 32767
THEN COL1::SMALLINT
ELSE NULL
END THE_NUMBER
FROM (
SELECT
COL1 ORIG_COL,
CASE
WHEN isnumber(COL1)
THEN COL1
ELSE NULL
END COL1
FROM test_cast
)
t1;
ORIG_COL | THE_NUMBER
----------+------------
NAN |
1 | 1
-+9,9.09 |
99999 |
(4 rows)
REGEXP_LIKE образец, используя шаблон, предлагаемый @Niederee в своем ответе на this question.
SELECT ORIG_COL,
CASE
WHEN COL1 BETWEEN -32678 AND 32767
THEN COL1::SMALLINT
ELSE NULL
END THE_NUMBER
FROM (
SELECT COL1 ORIG_COL,
CASE
WHEN REGEXP_LIKE(COL1, '^[+-]?[0-9]*[.]?[0-9]*$')
THEN COL1
ELSE NULL
END COL1
FROM test_cast
)
t1;
ORIG_COL | THE_NUMBER
----------+------------
99999 |
NAN |
1 | 1
-+9,9.09 |
(4 rows)
Имейте в виду, что вам понадобится ваш администратор, чтобы сделать любую из этих функций доступной для вас.
Функция ISNUMBER происходит от Инза установки, и если Инза на месте, может быть загружен так:
[[email protected] ~]$ cd /nz/extensions/nz/nzlua/examples/
[[email protected] examples]$ ../bin/nzl -d testdb isnumber.nzl
Compiling: isnumber.nzl
####################################################################
UdxName = isnumber
UdxType = UDF
Arguments = VARCHAR(ANY)
Result = BOOL
Dependencies = INZA.INZA.LIBNZLUA_3_2_0
NZUDXCOMPILE OPTIONS: (--replbyval --nullcall --unfenced --mem 2m)
CREATE FUNCTION
[[email protected] examples]$
Процедура установки инструментария SQL Выдвижение довольно хорошо документированы, и функция REGEXP_LIKE включена с этим.
Я предложил изменить ваш вопрос, чтобы включить конкретный тестовый пример, который вы упомянули в другом вопросе. Для этого потребуется немного времени. Тем временем посмотрите, помогает ли мой ответ. – ScottMcG
Для «ожидающего быстрого ответа», а затем также не отвечающего на полезный ответ, я с сожалением записал это вслух. – halfer