これは、例外をスローすることなく、すべてのケースを処理する必要があります:
--This handles dollar-signs, commas, decimal-points, and values too big or small,
-- all while safely returning an int.
DECLARE @IntString as VarChar(50) = '$1,000.'
SELECT CAST((CASE WHEN --This IsNumeric check here does most of the heavy lifting. The rest is Integer-Specific
ISNUMERIC(@IntString) = 1
--Only allow Int-related characters. This will exclude things like 'e' and other foreign currency characters.
AND @IntString NOT LIKE '%[^ $,.\-+0-9]%' ESCAPE '\'--'
--Checks that the value is not out of bounds for an Integer.
AND CAST(REPLACE(REPLACE(@IntString,'$',''),',','') as Decimal(38)) BETWEEN -2147483648 AND 2147483647
--This allows values with decimal-points for count as an Int, so long as there it is not a fractional value.
AND CAST(REPLACE(REPLACE(@IntString,'$',''),',','') as Decimal(38)) = CAST(REPLACE(REPLACE(@IntString,'$',''),',','') as Decimal(38,2))
--This will safely convert values with decimal points to casting later as an Int.
THEN CAST(REPLACE(REPLACE(@IntString,'$',''),',','') as Decimal(10))
END) as Int)[Integer]
スカラUDFにこれを投げるとReturnInt()それを呼び出します。
値がNULLとして戻ってきた場合、それはint型ではありません(そう、あなたのIsInteger()の要件があります)
あなたが「ReturnInt(someValueのは) NULLでない場合を」あなたは、可能性がタイピング好きではない場合IsInt()という別のスカラーUDFにこの関数を呼び出し、単に "ReturnInt(SomeValue)IS NOT NULL"を返します。
クールなことは、「安全に」をint値に変換して返すことで、UDFが二重の役割を果たすことです。
ちょうど何かの理由から、は、であることは、intとしてキャストすることを意味するものではありませんが、巨大な例外をスローしません。これはあなたのためにそれを処理します。
また、私は、この普遍的なアプローチではカンマ、小数点記号、ドル記号を処理し、許容可能なInt値の範囲をチェックするため、他のソリューションは避けたいと思います。パフォーマンスを最大化するためにスカラ関数のロジックを使用します。
以下の例を参照してください、私のコードや他の人に対してそれらをテストします。
--Proves that appending "e0" or ".0e0" is NOT a good idea.
select ISNUMERIC('$1' + 'e0')--Returns: 0.
select ISNUMERIC('1,000' + 'e0')--Returns: 0.
select ISNUMERIC('1.0' + '.0e0')--Returns: 0.
--While these are numeric, they WILL break your code
-- if you try to cast them directly as int.
select ISNUMERIC('1,000')--Returns: 1.
select CAST('1,000' as Int)--Will throw exception.
select ISNUMERIC('$1')--Returns: 1.
select CAST('$1' as Int)--Will throw exception.
select ISNUMERIC('10.0')--Returns: 1.
select CAST('10.0' as Int)--Will throw exception.
select ISNUMERIC('9999999999223372036854775807')--Returns: 1. This is why I use Decimal(38) as Decimal defaults to Decimal(18).
select CAST('9999999999223372036854775807' as Int)--Will throw exception.
更新:
私はあなたが123」のような値を解析することができるようにしたいことをここのコメントを読んで。 '整数に変換する。これを処理するコードも更新しました。
注:これは「1.0」を変換しますが、「1.9」にはnullを返します。
ROUND(CAST(REPLACE(REPLACE(@IntString、 '$'、 '')、 ')は、丸めを許可する場合は、「THEN」節のロジックを微調整してRound()を追加します。
ROUND (10))、0)
は丸めまたは切り捨てができるように小数点を確認する「AND」も削除する必要があります。
ここでのハックは、数字として扱うテキスト列にデータがあることです。あなたは本当にそれをしてはいけませんが、私はあなたがすでにその理由を発見したと思います。 –