Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Нужно сделать замену одного слова на другое  [new]
Andrew_vb1110
Member

Откуда: Симферополь
Сообщений: 540
Господа, мне нужно осуществить замену в текстовом поле одного слова:
КОФЕ
на слово:
КАВА

вот для примера входной набор записей:
НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ
МОЛОКО ДЛЯ КОФЕ И ЧАЮ РОМ ТМ КОМО ТП 6% ШТ 0,200ГР
МЫЛО ЖИДКОЕ АПАРТ КОФЕИН МЕНТОЛ 300 МЛ /ШТ
КРАСКА ДЛЯ ВОЛОС PALETTE КОЛОР N6-6 КОФЕ С
мне нужно поменять только 1,2 и 4 записи.

Т.е. выходной рекордсет должен быть:
НАБОР ДЛЯ КАВА 12 ПР 68420/5631 ШТ
МОЛОКО ДЛЯ КАВА И ЧАЮ РОМ ТМ КОМО ТП 6% ШТ 0,200ГР
МЫЛО ЖИДКОЕ АПАРТ КОФЕИН МЕНТОЛ 300 МЛ /ШТ
КРАСКА ДЛЯ ВОЛОС PALETTE КОЛОР N6-6 КАВА С
5 май 11, 09:59    [10607968]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Andrew_vb1110,

select replace('НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ', 'КОФЕ','КАВА')
5 май 11, 10:04    [10607992]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
Что значит текстовое поле, тип этого поля какой???
И версию сервера можно?
5 май 11, 10:05    [10607999]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Anatoly Podgoretsky
Member

Откуда:
Сообщений: 62908
Мне кажется что это ему изменит и слово кофеин
автор
Returns a string with all the instances of a substring replaced by another substring.
5 май 11, 10:09    [10608014]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
DeColo®es
Member

Откуда: Москва
Сообщений: 5503
Блог
Правильно будет как-то так:
(Начальные и конечные проблеы можно конечно и более "точно" обрезать)
declare @str varchar(255) = 'НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ'
select ltrim(rtrim(replace(' ' + @str + ' ', ' КОФЕ ',' КАВА ')))
5 май 11, 10:10    [10608022]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Anatoly Podgoretsky
Member

Откуда:
Сообщений: 62908
Не будет, КОФЕ может стоять в начали или в конце.
5 май 11, 10:12    [10608031]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Anatoly Podgoretsky
Member

Откуда:
Сообщений: 62908
Тут наверно надо применить регулярные выражение на поиск точного вхождения
5 май 11, 10:14    [10608035]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
А я вот все жду ответа вдруг у него поле и вправду типа TEXT
:)
5 май 11, 10:14    [10608037]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Andrew_vb1110
Member

Откуда: Симферополь
Сообщений: 540
angel_zar,

версия сервера:
Microsoft SQL Server 2005 - 9.00.3152.00 (Intel X86) Mar 3 2007 03:17:37 Copyright (c) 1988-2005 Microsoft Corporation Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

поле типа varchar(250)
5 май 11, 10:16    [10608046]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Andrew_vb1110
Member

Откуда: Симферополь
Сообщений: 540
Anatoly Podgoretsky,

да, строка вхождения может быть в любом месте
5 май 11, 10:17    [10608055]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Andrew_vb1110
Member

Откуда: Симферополь
Сообщений: 540
angel_zar,

типа varchar(250)
5 май 11, 10:18    [10608064]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
Andrew_vb1110
angel_zar,

версия сервера:
Microsoft SQL Server 2005 - 9.00.3152.00 (Intel X86) Mar 3 2007 03:17:37 Copyright (c) 1988-2005 Microsoft Corporation Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

поле типа varchar(250)


declare @str varchar(255) = 'НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ'
select ltrim(replace(' ' + @str, ' КОФЕ',' КАВА'))

Я б вот так попробовал.

Но смотря как текст конечно набран.
5 май 11, 10:20    [10608079]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
Хотя тоже наврал
5 май 11, 10:21    [10608082]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Andrew_vb1110
Member

Откуда: Симферополь
Сообщений: 540
angel_zar,

спасибо
5 май 11, 10:21    [10608084]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
Andrew_vb1110
angel_zar,

спасибо


Дык не правильно же сказал.
Вот подредактировано

declare @str varchar(255) 
set @str='НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ'
select ltrim(rtrim(Replace(replace(replace(' ' + @str + ' ', ' КОФЕ ',' КАВА '),' КОФЕ,',' КАВА,'),' КОФЕ.',' КАВА.')))

При условии что слово может стоять в конце и начале строки, обязательно перед словом пробел и заканчивается слово пробелом, точкой или запятой
5 май 11, 10:28    [10608141]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Гадя Петрович
Member

Откуда: планета Плюк, 215 в тентуре, галактика Кин-дза-дза в Спирали
Сообщений: 52912
angel_zar
При условии что слово может стоять в конце и начале строки, обязательно перед словом пробел и заканчивается слово пробелом, точкой или запятой
ну да, остальные знаки препинания не в чести :)
5 май 11, 10:31    [10608162]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
Гадя Петрович
angel_zar
При условии что слово может стоять в конце и начале строки, обязательно перед словом пробел и заканчивается слово пробелом, точкой или запятой
ну да, остальные знаки препинания не в чести :)


А чего того, могут люди и так написать
"молоко,кофе"
В данном случае тоже не сработает.
Как вариант сделать таблицу с чего может слово начинаться и чем заканчиваться, а уже функцией выполнять замену слова, согласно этим префиксам и постфиксам.
5 май 11, 10:36    [10608192]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
angel_zar,
а если будет "КОФЕ-БОДРЯЩИЙ НАПИТОК!"

я думал что надо подстроку заменить, но если именно слово - тогда чуть сложнее,а иемнно надо сначала определить правило по которому считать границы этого слова. Далее уже дело техники. Мне кажется логичным будет правило, если слева и справа от слова "КОФЕ" стоят не буквы - то выделяем этот фрагмент.
5 май 11, 10:37    [10608204]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Гадя Петрович
Member

Откуда: планета Плюк, 215 в тентуре, галактика Кин-дза-дза в Спирали
Сообщений: 52912
angel_zar
выполнять замену слова, согласно этим префиксам и постфиксам.
зачем так сложно?
достаточно проверить, не является ли следующий после КОФЕ символ буквой
5 май 11, 10:39    [10608209]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
angel_zar
Member

Откуда: Барнаул
Сообщений: 902
SomewhereSomehow
angel_zar,
а если будет "КОФЕ-БОДРЯЩИЙ НАПИТОК!"

я думал что надо подстроку заменить, но если именно слово - тогда чуть сложнее,а иемнно надо сначала определить правило по которому считать границы этого слова. Далее уже дело техники. Мне кажется логичным будет правило, если слева и справа от слова "КОФЕ" стоят не буквы - то выделяем этот фрагмент.


Вариантов много, и я не согласен что все что не буквы, можно считать началом и концом слова.
Слова бывают разные.
Особенно если это имя какое нибудь.
5 май 11, 10:43    [10608235]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
по сути конечно получится фигня, поскольку "кофе" м.род, не склоняется, а "кава" ж.р и склоняется в укр. языке.

"Набор для кофе ..." ->"Набор для кави ..." д.б..
5 май 11, 10:54    [10608326]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Заменит только первое вхождение требуемого слова:
declare @t table (id int identity, value varchar(max))
insert into @t (value)
values
 ('НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ'),
 ('МОЛОКО ДЛЯ КОФЕ И ЧАЮ РОМ ТМ КОМО ТП 6% ШТ 0,200ГР'),
 ('МЫЛО ЖИДКОЕ АПАРТ КОФЕИН МЕНТОЛ 300 МЛ /ШТ'),
 ('КРАСКА ДЛЯ ВОЛОС PALETTE КОЛОР N6-6 КОФЕ С ')

declare @delimiters varchar(30) = '[^а-яА-Яa-zA-Z]', @coffee varchar(30) = 'КОФЕ'

declare @p table (pattern varchar(max), offset int)
insert into @p
values
 ('%' + @delimiters + @coffee + @delimiters + '%', 1),
 ('%' + @delimiters + @coffee, 1),
 (@coffee + @delimiters + '%', 0)

;with cte as
(
 select
  t.id, min(p.i + p.offset) as i
 from
  @t t cross apply
  (select patindex(pattern, t.value) as i, offset from @p) p
 where
  p.i > 0
 group by
  t.id
)
update t
 set
  value = stuff(value, c.i, len(@coffee), 'КАВА')
from
 @t t join
 cte c on c.id = t.id

select * from @t
5 май 11, 12:57    [10609304]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Баян, конечно. Но всё же:
USE tempdb;
SET NOCOUNT ON;
IF OBJECT_ID(N'T','U') IS NOT NULL DROP TABLE T;
CREATE TABLE T(ID INT NOT NULL IDENTITY, S VARCHAR(255));
GO
INSERT T(S)
          SELECT 'НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ'
UNION ALL SELECT 'МОЛОКО ДЛЯ КОФЕ И ЧАЮ РОМ ТМ КОМО ТП 6% ШТ 0,200ГР'
UNION ALL SELECT 'МЫЛО ЖИДКОЕ АПАРТ КОФЕИН МЕНТОЛ 300 МЛ /ШТ'
UNION ALL SELECT 'КРАСКА ДЛЯ ВОЛОС PALETTE КОЛОР N6-6 КОФЕ С';

DECLARE @Delimiters VARCHAR(100);
/*Любые символы-разделители по вкусу*/
SET @Delimiters=' ,.()[]{}'+CHAR(9)+CHAR(10)+CHAR(13);

WITH CTE(ID,N,S) AS
/*Разборка строки на непрерывные последовательности разделителей и неразделителей (по одной последовательности на строке)*/
(
/*Символы - неразделители с указанием позиции в строке*/
 SELECT T.ID,V.number, SUBSTRING(T.S,V.number-1,
 (SELECT TOP(1) VV.number-V.number+2 FROM master.dbo.spt_values VV WHERE V.type='P' AND VV.number BETWEEN V.number-1 AND LEN(T.S)+1
  AND CHARINDEX(SUBSTRING(T.S+LEFT(@Delimiters,1),VV.number,1),@Delimiters)=0
  AND CHARINDEX(SUBSTRING(T.S+LEFT(@Delimiters,1),VV.number+1,1),@Delimiters)<>0
  ORDER BY VV.number))
 FROM T
 JOIN master.dbo.spt_values V ON V.type='P' AND V.number BETWEEN 1 AND LEN(T.S)+1
  AND CHARINDEX(SUBSTRING(LEFT(@Delimiters,1)+T.S,V.number,1),@Delimiters)=0
  AND CHARINDEX(SUBSTRING(LEFT(@Delimiters,1)+T.S,V.number-1,1),@Delimiters)<>0
 UNION ALL
/*Символы - разделители с указанием позиции в строке*/
 SELECT T.ID,V.number+1, SUBSTRING(T.S,V.number,
 (SELECT TOP(1) VV.number-V.number+1 FROM master.dbo.spt_values VV WHERE V.type='P' AND VV.number BETWEEN V.number AND LEN(T.S)
  AND CHARINDEX(SUBSTRING(T.S,VV.number,1),@Delimiters)<>0
  AND CHARINDEX(SUBSTRING(T.S,VV.number+1,1),@Delimiters)=0
  ORDER BY VV.number))
 FROM T
 JOIN master.dbo.spt_values V ON V.type='P' AND V.number BETWEEN 1 AND LEN(T.S)
  AND CHARINDEX(SUBSTRING(T.S,V.number,1),@Delimiters)<>0
  AND CHARINDEX(SUBSTRING(T.S,V.number-1,1),@Delimiters)=0
)
/*Сборка строк с заменой*/
SELECT ID,(SELECT CASE CTE1.S WHEN 'КОФЕ' THEN 'КАВА' ELSE CTE1.S END FROM CTE CTE1 WHERE CTE1.ID=CTE.ID ORDER BY CTE1.N FOR XML PATH(''), TYPE).value('.','VARCHAR(255)')
FROM CTE
GROUP BY ID
ORDER BY ID;
Может, надо ещё подточить слегка...
Можно приделать сюда таблицу замен вместо одной пары КОФЕ - КАВА. Совсем несложно.
Как всегда, вместо master.spt_values лучше иметь свою таблицу с числами.
Можно также использовать любую большую таблицу + ROW_NUMBER()OVER()
Или сгенерировать числа рекурсивным CTE (но это медленно)

P.S. CHARINDEX используется вместо LIKE во избежание проблем со спецсимволами LIKE (подробности сходу не скажу - подзабыл)
5 май 11, 15:39    [10610915]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
Andrew_vb1110
Member

Откуда: Симферополь
Сообщений: 540
iap
Баян, конечно. Но всё же:
USE tempdb;
SET NOCOUNT ON;
IF OBJECT_ID(N'T','U') IS NOT NULL DROP TABLE T;
CREATE TABLE T(ID INT NOT NULL IDENTITY, S VARCHAR(255));
GO
INSERT T(S)
          SELECT 'НАБОР ДЛЯ КОФЕ 12 ПР 68420/5631 ШТ'
UNION ALL SELECT 'МОЛОКО ДЛЯ КОФЕ И ЧАЮ РОМ ТМ КОМО ТП 6% ШТ 0,200ГР'
UNION ALL SELECT 'МЫЛО ЖИДКОЕ АПАРТ КОФЕИН МЕНТОЛ 300 МЛ /ШТ'
UNION ALL SELECT 'КРАСКА ДЛЯ ВОЛОС PALETTE КОЛОР N6-6 КОФЕ С';

DECLARE @Delimiters VARCHAR(100);
/*Любые символы-разделители по вкусу*/
SET @Delimiters=' ,.()[]{}'+CHAR(9)+CHAR(10)+CHAR(13);

WITH CTE(ID,N,S) AS
/*Разборка строки на непрерывные последовательности разделителей и неразделителей (по одной последовательности на строке)*/
(
/*Символы - неразделители с указанием позиции в строке*/
 SELECT T.ID,V.number, SUBSTRING(T.S,V.number-1,
 (SELECT TOP(1) VV.number-V.number+2 FROM master.dbo.spt_values VV WHERE V.type='P' AND VV.number BETWEEN V.number-1 AND LEN(T.S)+1
  AND CHARINDEX(SUBSTRING(T.S+LEFT(@Delimiters,1),VV.number,1),@Delimiters)=0
  AND CHARINDEX(SUBSTRING(T.S+LEFT(@Delimiters,1),VV.number+1,1),@Delimiters)<>0
  ORDER BY VV.number))
 FROM T
 JOIN master.dbo.spt_values V ON V.type='P' AND V.number BETWEEN 1 AND LEN(T.S)+1
  AND CHARINDEX(SUBSTRING(LEFT(@Delimiters,1)+T.S,V.number,1),@Delimiters)=0
  AND CHARINDEX(SUBSTRING(LEFT(@Delimiters,1)+T.S,V.number-1,1),@Delimiters)<>0
 UNION ALL
/*Символы - разделители с указанием позиции в строке*/
 SELECT T.ID,V.number+1, SUBSTRING(T.S,V.number,
 (SELECT TOP(1) VV.number-V.number+1 FROM master.dbo.spt_values VV WHERE V.type='P' AND VV.number BETWEEN V.number AND LEN(T.S)
  AND CHARINDEX(SUBSTRING(T.S,VV.number,1),@Delimiters)<>0
  AND CHARINDEX(SUBSTRING(T.S,VV.number+1,1),@Delimiters)=0
  ORDER BY VV.number))
 FROM T
 JOIN master.dbo.spt_values V ON V.type='P' AND V.number BETWEEN 1 AND LEN(T.S)
  AND CHARINDEX(SUBSTRING(T.S,V.number,1),@Delimiters)<>0
  AND CHARINDEX(SUBSTRING(T.S,V.number-1,1),@Delimiters)=0
)
/*Сборка строк с заменой*/
SELECT ID,(SELECT CASE CTE1.S WHEN 'КОФЕ' THEN 'КАВА' ELSE CTE1.S END FROM CTE CTE1 WHERE CTE1.ID=CTE.ID ORDER BY CTE1.N FOR XML PATH(''), TYPE).value('.','VARCHAR(255)')
FROM CTE
GROUP BY ID
ORDER BY ID;
Может, надо ещё подточить слегка...
Можно приделать сюда таблицу замен вместо одной пары КОФЕ - КАВА. Совсем несложно.
Как всегда, вместо master.spt_values лучше иметь свою таблицу с числами.
Можно также использовать любую большую таблицу + ROW_NUMBER()OVER()
Или сгенерировать числа рекурсивным CTE (но это медленно)

P.S. CHARINDEX используется вместо LIKE во избежание проблем со спецсимволами LIKE (подробности сходу не скажу - подзабыл)

Да, классическое решение. Спасибо. Есть чему поучиться :-)
6 май 11, 08:39    [10614307]     Ответить | Цитировать Сообщить модератору
 Re: Нужно сделать замену одного слова на другое  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Andrew_vb1110,

печёнкой чую, можно UNION и убрать...
Но это подумать надо. Времени нет сейчас
6 май 11, 09:17    [10614451]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить