19

そのため、古い信頼性 の低いものだけでなく、ストアド プロシージャ内で宣言されて呼び出されISNUMERICたときにのみ問題が発生することが判明した問題のトラブルシューティングに 5 時間を費やしました(私はたくさん持っています)。それをテストケースに抽出するために行う作業の量ですが、私の最初の必要性はそれを信頼できるものに置き換えることです)。ISNUMERICWITH SCHEMABINDING

の優れた効率的な代替品に関する推奨事項ISNUMERIC()int、などのバリエーションが本当に必要なのは明らかですがmoney、人々は何を使用していますか (できれば T-SQL で。このプロジェクトでは、これは大量の SQL Server から SQL Server へのデータであるため、SQL Server に制限されているためです)処理タスク)?

4

11 に答える 11

24

Bacon Bits がコメントで言及しているように、SQL Server 2012 を実行している場合は、T-SQL 関数 TRY_CAST() または TRY_CONVERT() を使用できます。

SELECT CASE WHEN TRY_CAST('foo' AS INT) IS NULL THEN 0 ELSE 1 END

SELECT CASE WHEN TRY_CAST(1 AS INT) IS NULL THEN 0 ELSE 1 END

SQL 2008 R2 以前を使用している場合は、.NET CLR 関数を使用し、System.Decimal.TryParse() をラップする必要があります。

于 2008-11-23T16:56:38.677 に答える
16

状況と検証のパフォーマンス特性に応じて、代わりに LIKE 式のバリエーションを使用することがあります。例えば:

NOT LIKE '%[^0-9]%'

この特定の例はかなり単純であることに注意してください。値が特定のデータ型への変換に対して有効であることは保証されません。また、必要に応じて +/- 記号や小数点を使用することもできません。

于 2008-11-23T15:58:58.557 に答える
6

もう1つのオプションは、拡張ストアドプロシージャをCなどの言語で記述し、それをDLLにして、SQLServerで使用できるようにすることです。

コードの行数が多すぎるとは思いません。また、CLRの読み込みで余分な耳が聞こえないため、.NETでマネージドストアドプロシージャを作成するよりも高速である可能性があります。

ここにちょっとした情報があります: http://msdn.microsoft.com/en-us/library/ms175200.aspx

これがあなたのために働くかもしれないいくつかのC++コードです:

using namespace std;

int checkNumber() {
  int number = 0;
  cin >> number;
  cin.ignore(numeric_limits<int>::max(), '\n');

  if (!cin || cin.gcount() != 1)
    cout << "Not a number.";
  else
    cout << "Your entered: " << number;
  return 0;
}
于 2009-01-27T20:49:39.800 に答える
3

.NET CLR ルートに従って、特に特定の範囲の数値が予想される場合は、正規表現を使用できます。

SQL 2005 と正規表現

于 2009-01-27T20:41:07.230 に答える
2

一般的に、型付けされていないデータをデータベースに入れないようにしています。アプリケーション層で処理するか、バッチ インポートの場合は SQL Integration Services で処理する方が適しているためです。開始。

私は過去に何度もそれをしなければなりませんでしたが、通常、最速の方法は、拡張ストアド プロシージャを呼び出すオーバーヘッドがほとんどの場合、データが期待する形式であることを確認する独自のユーザー定義関数を作成することです。または単純な検証用のマネージ コードは、T-SQL で実行するよりも遅くなります。

于 2008-11-23T13:15:02.837 に答える
1

SQLServer2005以降の場合....try/catchを利用してください...

declare @test varchar(10), @num decimal
select @test = '0123A'

begin try
    select @num = cast(@test as decimal)
    print '1'
end try 
begin catch
    print '0'
end catch

0を出力します。

@test='01234'または@test='01234.5'を変更すると、1が出力されます。

于 2010-03-24T18:23:43.553 に答える
1

これら2つの機能を実装するのはどうですか:

CREATE FUNCTION dbo.isReallyNumeric  
(  
    @num VARCHAR(64)  
)  
RETURNS BIT  
BEGIN  
    IF LEFT(@num, 1) = '-'  
        SET @num = SUBSTRING(@num, 2, LEN(@num))  

    DECLARE @pos TINYINT  

    SET @pos = 1 + LEN(@num) - CHARINDEX('.', REVERSE(@num))  

    RETURN CASE  
    WHEN PATINDEX('%[^0-9.-]%', @num) = 0  
        AND @num NOT IN ('.', '-', '+', '^') 
        AND LEN(@num)>0  
        AND @num NOT LIKE '%-%' 
        AND  
        (  
            ((@pos = LEN(@num)+1)  
            OR @pos = CHARINDEX('.', @num))  
        )  
    THEN  
        1  
    ELSE  
    0  
    END  
END  
GO  

CREATE FUNCTION dbo.isReallyInteger  
(  
    @num VARCHAR(64)  
)  
RETURNS BIT  
BEGIN  
    IF LEFT(@num, 1) = '-'  
        SET @num = SUBSTRING(@num, 2, LEN(@num))  

    RETURN CASE  
    WHEN PATINDEX('%[^0-9-]%', @num) = 0  
        AND CHARINDEX('-', @num) <= 1  
        AND @num NOT IN ('.', '-', '+', '^') 
        AND LEN(@num)>0  
        AND @num NOT LIKE '%-%' 
    THEN  
        1  
    ELSE  
        0  
    END  
END  
GO

元のソース

于 2009-01-30T09:44:15.487 に答える
1

Microsoft のサポートによると、UDF 関数を置き換える唯一の効率的な方法は、独自の .NET 関数バージョンを作成することです。

もちろん、データベース管理者がそれを許可している場合:)。

私はしません:(。

于 2008-11-23T15:24:49.190 に答える
0

SQL 2012 以降では、ISNUMERIC() の代わりに TRY_PARSE() 関数を使用できます。

SELECT
 TRY_PARSE('123' as int) as '123'
,TRY_PARSE('abc' as int) as 'abc'
于 2015-10-07T11:02:25.397 に答える
0

IsNumeric() は、スペース、「D」、「E」、ドル記号、およびその他のあらゆる種類の文字に問題があるようです。通常必要なのは、CAST または CONVERT が成功するかどうかを示すものです。この UDF は最速のソリューションではありませんが、私にとっては非常にうまく機能しています。

create function dbo.udf_IsNumeric(@str varchar(50))
  returns int
as
begin
  declare @rtn int
  select @rtn =
    case
      when ltrim(rtrim(@str)) in('.', '-', '-.', '+', '+.') then 0
      when ltrim(rtrim(@str)) like '%[^-+.0-9]%' then 0
      else isnumeric(@str)
    end
  return @rtn
end
于 2009-10-17T02:02:28.913 に答える
0

中国語など、自分の (人間の) 言語以外の番号システムを扱う予定はありますか? もしそうなら、libuninum ライブラリを使用することをお勧めします。

于 2008-11-23T08:22:46.310 に答える