#sql #sql-server #substring #charindex
#sql #sql-сервер #подстрока #charindex
Вопрос:
Может кто-нибудь сказать мне, где я ошибаюсь, кажется, я не могу извлечь четвертое слово CCC, перепробовал все, не хочу помещать его в таблицу, просто возвращая подстроку в select?
DECLARE @ProductCode VARCHAR(256)
SET @ProductCode = 'CCCC-DDDDDDD-AAA-CCC-BBBBB'
SELECT LEFT(@ProductCode,CHARINDEX('-',@ProductCode) - 1) AS CHAR1,
SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode) 1,
CHARINDEX('-',@ProductCode,CHARINDEX('-', @ProductCode) 1) - (CHARINDEX('-',@ProductCode) 1)) AS CHAR2,
SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode,CHARINDEX('-',@ProductCode) 1) 1,
DATALENGTH(@ProductCode) - CHARINDEX('-', @ProductCode,CHARINDEX('-',@ProductCode) 1) - CHARINDEX('-',REVERSE(@ProductCode))) AS CHAR3,
SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode,CHARINDEX('-',@ProductCode), CHARINDEX('-',@ProductCode) 1)) 1,
DATALENGTH(@ProductCode) - CHARINDEX('-', @ProductCode,CHARINDEX('-',@ProductCode), CHARINDEX('-',@ProductCode) 1) - CHARINDEX('-',REVERSE(@ProductCode))) AS CHAR4,
RIGHT(@ProductCode,CHARINDEX('-',REVERSE(@ProductCode)) - 1) AS LASTCHAR
GO
Большое спасибо
Комментарии:
1. Сделайте себе одолжение и найдите функцию разделения строк, которая обеспечивает порядковую позицию. В какой-то момент MS улучшит встроенную функцию, чтобы сделать то же самое. Для добавления TRIM потребовалось всего 17 лет.
2. И использование datalength логически неверно. Если вам когда-нибудь понадобится использовать строки с nvarchar, ваш код не будет работать.
3. Строка, которую вы пытаетесь извлечь, всегда находится в одной и той же позиции?
Ответ №1:
Возможно, было бы проще, поскольку:
select s.value
from string_split(@productcode, '-') s
where @productcode like '%-%-%-' s.value '-%' and
@productcode not like '%-%-%-%-' s.value '-%' and
Комментарии:
1. Для STRING_SPLIT требуется, чтобы уровень совместимости был не менее 130
2. @JohnJoseph . , , Или сформулированный по-другому, он доступен с текущего выпуска 2016-06-01 — около четырех с половиной лет.
3. Итак, предполагая, что вы пытаетесь быть полезным, а не придирчивым … если у OP есть SQL Server 2014 или более ранняя версия, не будет возможности изменить совместимость на 130 или выше.
Ответ №2:
ниже приведен один из подходов к выполнению задачи:
select substring(@productcode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode)) 1) 1) 1,datalength(@productcode)-charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode,charindex('-',@ProductCode)) 1) 1) 1)-2);
Вы путаетесь, используя множественный подход для извлечения
строки. Вам не нужна ОБРАТНАЯ ФУНКЦИЯ, чтобы получить окончание строки
, вы можете просто продолжать извлекать позицию ‘-‘ с помощью
функции charindex и вычитать ее из общей длины строки.
Ответ №3:
Преимущество этого подхода в том, что он удобочитаем, но он уродлив…
DECLARE @ProductCode VARCHAR(256)
SET @ProductCode = 'CCCC-DDDDDDD-AAA-CCC-BBBBB'
select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode) 1,99)
select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode) 1,99)
select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode) 1,99)
select @ProductCode = left(@ProductCode,charindex('-',@ProductCode)-1)
select @ProductCode
Ответ №4:
--get 3rd and 4th words (the same way as for the 2nd word)
DECLARE @ProductCode VARCHAR(256)
SET @ProductCode = 'CC12CC-DDD34DD-A56A-C78C-BB910BB'
SELECT LEFT(@ProductCode,CHARINDEX('-',@ProductCode) - 1) AS CHAR1,
SUBSTRING(@ProductCode,CHARINDEX('-',@ProductCode) 1,
CHARINDEX('-',@ProductCode,CHARINDEX('-', @ProductCode) 1) - (CHARINDEX('-',@ProductCode) 1)) AS CHAR2,
SUBSTRING(
@ProductCode,
--.. from position of 2nd "-" plus one
CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) 1) 1,
--as many chars as there are between 2ndamp;3rd "-"
CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) 1) 1) -1 --3rd "-" minus 1
- --minus position 2nd "-"
CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) 1) --= chars between 2nd and 3rd "-"
) as xCHAR3,
SUBSTRING(
@ProductCode,
--.. from position of 3rd "-" plus one
CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) 1) 1) 1,
--get as many chars as there are between 3rdamp;4th "-"
CHARINDEX('-', @ProductCode, CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) 1) 1) 1) -1 --4th "-" minus 1
- --minus position 3rd "-"
CHARINDEX('-', @ProductCode, CHARINDEX('-',@ProductCode, CHARINDEX('-', @ProductCode) 1) 1) --= chars between 3rd and 4th "-"
) as xCHAR4,
RIGHT(@ProductCode,CHARINDEX('-',REVERSE(@ProductCode)) - 1) AS LASTCHAR
GO
--... or ...
DECLARE @ProductCode VARCHAR(256);
SET @ProductCode = 'CC12CC-DDD34DD-A56A-C78C-BB910BB';
select
p.value('comment()[1]', 'varchar(100)') as char1,
p.value('comment()[2]', 'varchar(100)') as char2,
p.value('comment()[3]', 'varchar(100)') as char3,
p.value('comment()[4]', 'varchar(100)') as char4,
p.value('comment()[5]', 'varchar(100)') as char5
from
(
--splitting on '-', xml comment is rather safe
select cast('<!--' replace(@ProductCode, '-', '--><!--') '-->' as xml) p
) as t;
Ответ №5:
Преимущество этого подхода в том, что он является гибким, поскольку вы можете изменить N-е искомое слово…
declare @ProductCode varchar(256)
declare @WordSought int = 4
declare @Cntr int = 0
set @ProductCode = 'CCCC-DDDDDDD-AAA-CCC-BBBBB'
while @cntr < @WordSought - 1
begin
select @ProductCode = substring(@ProductCode,charindex('-',@ProductCode) 1,99)
set @cntr = @cntr 1
end
select left(@ProductCode,charindex('-',@ProductCode '-') - 1)