PATINDEX, подстановочные знаки и переменные

Как заставить PATINDEX выполнять сопоставление с подстановочным знаком для переменной, содержащей символ %?

В следующем я хочу, чтобы PATINDEX возвращал начальную позицию «% 3d»:

DECLARE @inputText as VARCHAR(100)
DECLARE @s as Int   
DECLARE @cIn as CHAR(3)

SET @inputText = 'OEi49j3DNxE%3d'
SET @cIn = '%3d'
SET @s = PATINDEX('%' + @cIn +'%', @InputText)

Как видно из @InputText, это начинается с позиции 12.

OEi49j3DNxE %3d

Однако PATINDEX, кажется, возвращает начальную позицию в 7, потому что кажется, что % отбрасывается из CIn:

OEi49j3DNxE%3d

Как мне найти %3d, как указано, а не 3d?


person Matt Hall    schedule 05.05.2017    source источник


Ответы (3)


Вы должны избежать знака %, обернув его []. Чтобы сделать это, вам нужно будет увеличить вашу переменную @cIn, чтобы вместить дополнительные 2 символа, и просто выполнить замену перед тем, как вы сделаете патиндекс, или вы можете сделать это встроенным, не изменяя размеры переменных.

DECLARE @inputText as VARCHAR(100)
DECLARE @s as Int   
DECLARE @cIn as CHAR(5)

SET @inputText = 'OEi49j3DNxE%3d'
SET @cIn = '%3d'
SET @cIn = REPLACE(@cIn, '%', '[%]')
SET @s = PATINDEX('%' + @cIn +'%', @InputText)

OR

DECLARE @inputText as VARCHAR(100)
DECLARE @s as Int   
DECLARE @cIn as CHAR(5)

SET @inputText = 'OEi49j3DNxE%3d'
SET @cIn = '%3d'
SET @s = PATINDEX('%' + replace(@cIn, '%', '[%]') +'%', @InputText)

Подробнее об этом можно прочитать здесь: Как избежать знак процента в T-SQL?

person Avitus    schedule 05.05.2017
comment
Проголосовал за ответ, так как предоставленный альтернативный вариант сработал для меня (cIn используется в другом месте, и его сохранение как [%]3d вызывает другие проблемы). Спасибо за это :) - person Matt Hall; 06.05.2017

DECLARE @inputText as VARCHAR(100)
DECLARE @s as Int   
DECLARE @cIn as CHAR(3)

SET @inputText = 'OEi49j3DNxE%3d'
SET @cIn = '[%]3d'
SET @s = PATINDEX('%' + @cIn + '%' , @InputText)

select @s

Выход: 12

person GandRalph    schedule 05.05.2017
comment
Правильно, большое спасибо - пошел только с @Avitus, поскольку предоставленная альтернатива лучше работала в моем полном коде. Спасибо. - person Matt Hall; 06.05.2017

person    schedule
comment
Совершенно верно - использовал только @Avitus, поскольку предоставленная альтернатива лучше работала в моем полном коде. Спасибо. - person Matt Hall; 06.05.2017