The following code is resulting in an infinite loop or really really slow execution:
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;
The input/output should be as follows:
- ‘abcdef’ -> ‘abcdef’ works ok
- ‘abc-def’ -> ‘abc-def’ results in infinite loop
- ‘abc*def’ -> ‘abc-def’ results in infinite loop
- etc.
Please help!
Returns
So it seems that for
varchardatatypes a trailing-is treated as being part of a set whereas fornvarcharit is ignored (treated as a malformed range asais ignored too?)The BOL entry for LIKE doesn’t explicitly talk about how to use
-within[]to get it to be treated as part of a set but does have the exampleto match
-, a, c, d, or fso I assume that it needs to be the first item in a set (i.e. that[^a-zA-Z0-9.~_-]needs to be altered to[^-a-zA-Z0-9.~_]). That also matches the result of my testing above.