1

次のコードは、無限ループまたは実行速度の低下を招きます。

CREATE FUNCTION [dbo].[CleanUriPart] 
(
    -- Add the parameters for the function here
    @DirtyUriPart nvarchar(200)
)

RETURNS nvarchar(200)
AS
BEGIN;
    -- Declare the return variable here
    DECLARE @Result nvarchar(200);

DECLARE @i int;

SET @i = 1;

WHILE 1 = 1
BEGIN;
    SET @i = PATINDEX('%[^a-zA-Z0-9.~_-]%', @DirtyUriPart COLLATE Latin1_General_BIN);
    IF @i > 0
        SET @DirtyUriPart = STUFF(@DirtyUriPart, @i, 1, '-');
    ELSE
        BREAK;
END;

-- Add the T-SQL statements to compute the return value here
SELECT @Result = @DirtyUriPart;

-- Return the result of the function
RETURN @Result;

END;

入出力は次のようになります。

  • 'abcdef'->'abcdef'は正常に機能します
  • 'abc-def'->'abc-def'は無限ループになります
  • 'abc *def'->'abc-def'は無限ループになります

助けてください!

4

3 に答える 3

2
SELECT PATINDEX('%[^a-]%', N'aaa-def' COLLATE Latin1_General_BIN),
       PATINDEX('%[^-a]%', N'aaa-def' COLLATE Latin1_General_BIN), 
       PATINDEX('%[^a-]%', 'aaa-def' COLLATE Latin1_General_BIN),
       PATINDEX('%[^-a]%', 'aaa-def' COLLATE Latin1_General_BIN)

戻り値

----------- ----------- ----------- -----------
1           5           5           5

したがって、varcharデータ型の場合、末尾-はセットの一部として扱われるのに対し、nvarcharそれは無視されるようです (無視されるように不正な範囲として扱われaますか?)

LIKEの BOL エントリは、セットの一部として扱われるようにするために-withinを使用する方法について明示的に述べていませんが、例があります[]

LIKE '[-acdf]'

一致-, a, c, d, or fするため、セットの最初のアイテムである必要があると想定しています(つまり、[^a-zA-Z0-9.~_-]に変更する必要があります[^-a-zA-Z0-9.~_])。これは、上記の私のテスト結果とも一致します。

于 2012-05-20T20:39:42.903 に答える
1

@DirtyUriPart が NULL と評価される可能性はありますか? PATINDEX 関数では、パターンまたは式のいずれかが NULL の場合、PATINDEX は NULL を返し、この場合の NULL は無限ループを引き起こします。

于 2012-05-20T20:13:18.093 に答える
0

@DirtyUriPartのようVARCHAR(200)にキャストすることで問題を解決できるようですPATINDEX。これにより、クラス内の他の文字とともにダッシュが認識されます。

DECLARE @DirtyUriPart nvarchar(200)='abc-def';

-- Returns 0
SELECT PATINDEX('%[^a-zA-Z0-9.~_-]%', CAST(@DirtyUriPart AS VARCHAR(200)) COLLATE Latin1_General_BIN);

-- Returns 4
SELECT PATINDEX('%[^a-zA-Z0-9.~_-]%', @DirtyUriPart COLLATE Latin1_General_BIN);
于 2012-05-20T21:16:21.980 に答える