SQL Server НЕ гарантирует короткое замыкание логического оператора, см. О коротком замыкании логического оператора SQL Server . Таким образом, все решения, использующие ISNUMERIC(...) AND CAST(...)
, в корне ошибочны (они могут работать, но в дальнейшем они могут произвольно потерпеть неудачу в зависимости от созданного плана). Лучшее решение - использовать CASE, как предлагает Томас: CASE ISNUMERIC(...) WHEN 1 THEN CAST(...) ELSE NULL END
. Но, как указал gbn, ISNUMERIC
общеизвестно привередлив в определении того, что означает «числовое», и во многих случаях, когда можно ожидать, что он вернет 0, он возвращает 1. Итак, смешивая CASE с LIKE:
CASE WHEN MyRow NOT LIKE '%[^0-9]%' THEN CAST(MyRow as bigint) ELSE NULL END
Но реальная проблема заключается в том, что если у вас есть миллионы строк, и вы должны искать их таким образом, вы всегда будете заканчивать сканирование сквозным, так как выражение не поддерживает SARG (независимо от того, как мы переписываем Это). Реальная проблема здесь заключается в чистоте данных, и ее следует решать на соответствующем уровне, где данные заполняются. Еще одна вещь, которую следует учитывать, - это если возможно создать постоянный вычисляемый столбец с этим выражением и создать отфильтрованный индекс, который исключает NULL (т. Е. Не числовой). Это немного ускорит процесс.