3

「、」に対してtrueを返すsqlserverのISNUMERIC関数に問題があります

郵便番号を解析して、2 番目の文字 (数字であるはず) が 0 であるかどうかを確認し、それぞれの場合で異なることをしようとしています。問題は、最初に isNumeric をチェックして char をキャストできないことです。これは、スカラー値関数が 2 番目の char 位置の数字を返し、それが数字でない場合は -1 を返すコードです。

@declare firstDigit int

IF ISNUMERIC(SUBSTRING(@postal,2,1) AS int) = 1
   set @firstDigit = CAST(SUBSTRING(@postal,2,1) AS int)
ELSE
   set @firstDigit = -1       

RETURN @firstdigit

郵便番号が完全に有効でない場合、これは失敗するためです。nvarchar @postal の 2 番目の文字が 0 ~ 9 の数字であるかどうかを確認する方法を見つけようとしています。LIKE [0-9]usingや usingPATINDEXなど、さまざまな種類のソリューションを見てきました。

これを行うためのより良い/より簡単な方法はありますか?そうでない場合、どの方法が最速ですか?

編集: Aaron Bertrand の提案に従ってコードが追加されました

ON z.postal = 
   CASE
      WHEN CONVERT(INT, CASE WHEN SUBSTRING(v.patientPostal,2,1) LIKE '[0-9]' 
          THEN SUBSTRING(v.patientPostal, 2,1) END) = 0 then v.patientPostal
      WHEN CONVERT(INT, CASE WHEN SUBSTRING(v.patientPostal,2,1) LIKE '[0-9]' 
          THEN SUBSTRING(v.patientPostal, 2,1) END) > 0 then LEFT(v.patientPostal,3)
4

3 に答える 3

9

WHERE col LIKE '[0-9]'とあなたが思いついた他の方法との違いを検出できるとしたら、私は非常に驚くでしょう. しかし、私はデニスに同意します。それを関数に入れて、すべてのコードで一貫して同じチェックを使用するようにします (または、少なくとも、大規模なスキャンなどのために UDF を回避している場合は、コードにマーカーを配置します。後で大規模に変更しやすくします)。

とはいえ、スカラー UDF を使用するだけで、関数内で解析するために使用する方法よりも多くのパフォーマンス ヒットが見られることは間違いありません。を使用してインラインで実行する場合と、UDF のパフォーマンスを比較する必要がありCASEます。例えば

SELECT Postal = CONVERT(INT, CASE WHEN SUBSTRING(postal,2,1) LIKE '[0-9]' 
       THEN SUBSTRING(postal, 2,1) END)
FROM ...

これはNULL、文字が数値でない場合に発生します。

ローカル変数のチェックだけを扱っている場合は、どの解析方法を使用してもかまわないので、最適化の取り組みを別の場所に集中させたほうがよいでしょう。

JOIN示されている句に提案を追加して編集します。これにより、一定のスキャンが少なくなる可能性がありますが、はるかに読みやすくなります (部分文字列の呼び出しがはるかに少なくなるなど)。

;WITH v AS 
(
    SELECT /* other columns, */ patientPostal, 
      ss = SUBSTRING(v.patientPostal,2,1),
      FROM [whatever table is aliased v in current query]
)
SELECT /* column list */
FROM [whatever table is aliased z in current query]
INNER JOIN v ON z.postal = CONVERT(INT, CASE 
    WHEN v.ss = '0' THEN ss
    WHEN v.ss LIKE '[1-9]' THEN LEFT(v.patientPostal, 3)
END);
于 2011-09-22T18:03:01.387 に答える
3

これを行う最良の方法は次のとおりです。

IF SUBSTRING(@postal,2,1) LIKE [0-9]
CAST(SUBSTRING(@postal,2,1) AS int)
于 2011-09-22T18:03:23.253 に答える
1

IsNumeric、IsInt、IsNumberを見てください。これらの3つのタイプをチェックしています。

于 2011-09-22T18:00:24.273 に答える