2015-02-18 8 views
0

Я пытаюсь обработать строку так, чтобы были сделаны только заглавные буквы и цифры. Пытаясь использовать PATINDEX, потому что я хочу сохранить это кратким - это будет частью большого запроса.Извлечь заглавные буквы и цифры

Есть немало примеров, показывающих что-то подобное, однако я, кажется, что-то пропускаю. До сих пор у меня есть

DECLARE @string varchar(100) 

SET @string = 'AbcDef12-Ghi' 

WHILE PATINDEX('%[^A-Z0-9]%',@string) <> 0 
    SET @string = STUFF(@string,PATINDEX('%[^A-Z0-9]%',@string),1,'') 

SELECT @string 

Как, например, this question, однако, похоже, это не делает то, что мне нужно.

Использование [^0-9] выводов 12, что является правильным.

Однако [^A-Z] выходы AbcDefGhi, то есть как в верхнем, так и в нижнем регистре. Не имеет значения, пользуюсь ли я [^A-Z] или [^a-z], оба возвращают все буквы.

Я думаю, что я могу пропустить что-то простое? Я нашел несколько предложений, относящихся к сортировке, и попытался использовать COLLATE с PATINDEX согласно this, но не смог заставить его работать.

Примечание: Я делаю это как одноразовый запрос в базе данных SQL Server, чтобы найти некоторые данные - это не будет использоваться повторно нигде, чтобы такие вещи, как производительность, SQL-инъекция (часто упоминается в этом контексте) и т. Д. не являются проблемой.

+1

Это не регулярное выражение. – Paparazzi

+0

Возможно, вы могли бы использовать таблицу tally + substring для 1 символа и сравнить ее с допустимыми символами? Что-то подобное, что DelimitedSplit8k использует http://www.sqlservercentral.com/articles/Tally+Table/72993/ –

+0

@Blam thanks - Я сделал больше исследований по этому вопросу. JamesZ, решение ниже работает для меня, и я не зарегистрирован в SQL Server Central. – Boris

ответ

5

Вы можете сделать это с помощью COLLATE и чувствительны к регистру параметры сортировки, такие как Latin1_General_BIN:

DECLARE @string varchar(100) 

SET @string = 'AbcDef12-Ghi' 

WHILE PATINDEX('%[^A-Z0-9]%',@string COLLATE Latin1_General_BIN) <> 0 
BEGIN 
    SET @string = STUFF(
     @string, 
     PATINDEX('%[^A-Z0-9]%',@string COLLATE Latin1_General_BIN),1,'' 
    ) 
END 

SELECT @string 

Это Выведет:

AD12G

+0

Спасибо за помощь, это работает! Странно, я помню, как это пробовал именно с Latin1_General_BIN вчера, но, возможно, это работает только в том случае, если это не 5 вечера: P – Boris

+0

Логика в целом понятна и звучит, но я бы использовал переменную для хранения результата PATINDEX, чтобы избежать двойного вызова функции каждая итерация. –

+1

@AndriyM Вы правы, и я, как правило, делаю это, но OP заявил в вопросе, что это разовый и производительность не проблема. – DavidG

Смежные вопросы