8

どうすれば達成できますか:

select * from table where column_value is int

おそらくシステムテーブルと型テーブルに内部結合できることはわかっていますが、もっとエレガントな方法があるかどうか疑問に思っています。

column_value は int を持つことができる varchar ですが、必ずしもそうではないことに注意してください。

多分私はそれをキャストしてエラーをトラップすることができますか?しかし、繰り返しますが、それはハックのようです。

4

6 に答える 6

3
select * from table
where column_value not like '[^0-9]'

負の整数が許可されている場合は、次のようなものが必要です

where column_value like '[+-]%' 
and substring(column_value,patindex('[+-]',substring(column_value,1))+1,len(column_value))
not like '[^0-9]'

column_value が「int」型の制限を超える整数になる可能性があり、そのようなケースを除外したい場合は、さらにコードが必要です。

于 2009-09-04T05:10:31.937 に答える
2

カスタム関数を実装する場合はこちら

CREATE Function dbo.IsInteger(@Value VARCHAR(18))
RETURNS BIT
AS 
BEGIN    
     RETURN ISNULL(     
         (SELECT    CASE WHEN CHARINDEX('.', @Value) > 0 THEN 
                            CASE WHEN CONVERT(int, PARSENAME(@Value, 1)) <> 0  THEN 0  ELSE 1 END  
                    ELSE 1 
                    END      
          WHERE     ISNUMERIC(@Value + 'e0') = 1), 0)

END

ISNUMERIC は、入力式が有効な整数、浮動小数点数、金額、または小数型に評価される場合に 1 を返します。それ以外の場合は 0 を返します。戻り値が 1 の場合、expression をこれらの数値型のいずれかに変換できることが保証されます。

于 2009-09-04T07:14:38.877 に答える
0

これは、例外をスローすることなく、すべてのケースを処理する必要があります。

--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]

これを Scalar UDF にスローし、それをReturnInt()と呼びます。
値が NULL として返される場合、それは int ではありません (したがって、IsInteger() 要件があります)。

「 WHERE ReturnInt(SomeValue) IS NOT NULL 」と入力したくない場合は、それをIsInt()という別のスカラー UDF にスローして、この関数を呼び出し、単純に「ReturnInt(SomeValue) IS NOT NULL」を返すことができます。

すばらしいことに、UDF は "安全に" 変換された int 値 を返すことで、2 つの役割を果たします。
何かが int になる可能性があるからといって、それを int としてキャストしても大きな例外がスローされないわけではありません。これはあなたのためにそれを処理します。

また、この普遍的なアプローチはコンマ、小数、ドル記号を処理し、許容可能な Int 値の範囲をチェックしますが、他のソリューションは処理しないため、他のソリューションは避けます。または、ロジックを使用できないようにする複数の SET 操作が必要です。最大のパフォーマンスのためのスカラー関数。

以下の例を参照して、私のコードや他のコードに対してテストしてください。

--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 を返します。
丸めを許可する場合は、"THEN" 句のロジックを微調整して、次のように Round() を追加します。
ROUND(CAST(REPLACE(REPLACE(@IntString,'$',''),',',') ') as Decimal(10)), 0) 丸めまたは切り捨てを可能にするために、「小数点」をチェックする「AND」も削除する必要
があります。

于 2012-05-18T01:52:05.207 に答える
0

Svetlozar Angelov が示唆するように UDF を実行しますが、最初に ISNUMERIC をチェックし (そうでない場合は 0 を返します)、次にそれcolumn_value % 1 = 0が整数かどうかをチェックします。

これが体の外観です。値が数値でない場合は例外がスローされるため、モジュロ ロジックを別のブランチに配置する必要があります。

DECLARE @RV BIT
IF ISNUMERIC(@value) BEGIN
    IF CAST(@value AS NUMERIC) % 1 = 0 SET @RV = 1
    ELSE SET @RV = 0
END
ELSE SET @RV = 0
RETURN @RV
于 2009-09-04T13:21:53.780 に答える
0

以下を使用して 1 をテストしてみませんか?

DECLARE @TestValue nvarchar(MAX)
SET @TestValue = '1.04343234e5'

SELECT CASE WHEN ISNUMERIC(@TestValue) = 1
        THEN CASE WHEN ROUND(@TestValue,0,1) = @TestValue
            THEN 1
            ELSE 0
            END
        ELSE null
        END AS Analysis
于 2012-06-04T23:38:33.747 に答える