Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Чувствительность к регистру (функция replace)  [new]
Алексей??????????
Guest
Проблема в том, что в поле name таблицы закачаны строки, содержащие некоторые(не все) символы в неправильной кодировке в верхнем и нижнем регистре. можно поменять их функцией replace. В результате меняет символы и в нижнем и в верхнем регистрах. Как сделать замену регистрочувствительной?
20 дек 02, 16:05    [94887]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
Проще всего, наверное, свою функцию написать ...
20 дек 02, 16:11    [94890]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145700
Для 7, пожалуй примерно так

set nocount on

declare @s varchar(20),
@b varbinary(20),
@b11 binary(1), @b12 binary(1),
@b21 binary(1), @b22 binary(1)

set @s='AAAaaaCCCccc'
set @b=convert(varbinary(20),@s)

set @b11=convert(varbinary(1),'a')
set @b12=convert(varbinary(1),'b')

set @b21=convert(varbinary(1),'c')
set @b22=convert(varbinary(1),'d')

declare @i int
set @i=1

while @i<=len(@s)
begin
select @b=
case when substring(@b,@i,1)=@b11
then convert(varbinary(20),stuff(@b,@i,1,@b12)) else
case when substring(@b,@i,1)=@b21
then convert(varbinary(20),stuff(@b,@i,1,@b22)) else
@b end end

set @i=@i+1
end

set @s=convert(varchar(20),@b)

select @s
20 дек 02, 17:58    [94980]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
jimmers
Member

Откуда: Санкт-Петербург - New York City
Сообщений: 5069
REPLACE чувствительна к регистру.
При условии, что аргумент (поле name) имеет case-sensitive collation.
20 дек 02, 18:14    [94992]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Александр Степанов
Member

Откуда: Санкт-Петербург
Сообщений: 545
Если версия сервера 2000, то можно воспользоваться COLLATE, например (коллейшн базы по умолчанию - Latin1_General_CI_AS):

DECLARE @field nvarchar(100), @what nvarchar(100), @to nvarchar(100)


Set @field='A StRiNg'
Set @what='string'
Set @to='XXXXXX'

Select
replace(@field,@what,@to),
replace(@field collate Latin1_General_CS_AS,@what collate Latin1_General_CS_AS,@to)
21 дек 02, 13:42    [95133]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Fil
Member

Откуда: Dnepropetrovsk
Сообщений: 9
declare @up varchar(80)

set @up='ASerTYUhjk'

select upper(@up)

set @up='ASerTYUhjk'

select lower(@up)


результат:

1.ASERTYUHJK

2.asertyuhjk
21 дек 02, 15:05    [95150]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
Cat2, здравствуйте!

Тоже возникла такая задача, но на MS SQL Server 2017. Ваш скрипт подойдёт? Или может там уже придумали регистрочувствительные функции подмены?
5 авг 19, 15:48    [21942182]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Борис Гаркун
Cat2, здравствуйте!

Тоже возникла такая задача, но на MS SQL Server 2017. Ваш скрипт подойдёт? Или может там уже придумали регистрочувствительные функции подмены?

Чем вам вариант с collate не нравится?
5 авг 19, 15:52    [21942185]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
Minamoto,

потому что вызов
replace('h' collate Latin1_General_CS_AS, 'h' collate Latin1_General_CS_AS, 'н')

почему-то возвращает ?
5 авг 19, 15:59    [21942193]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
iap
Member

Откуда: Москва
Сообщений: 46983
Борис Гаркун
Minamoto,

потому что вызов
replace('h' collate Latin1_General_CS_AS, 'h' collate Latin1_General_CS_AS, 'н')


почему-то возвращает ?
1. Cat2 здесь вряд ли появится.
2. У вас юникод (nvarchar)?
5 авг 19, 16:31    [21942217]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Борис Гаркун
Minamoto,

потому что вызов
replace('h' collate Latin1_General_CS_AS, 'h' collate Latin1_General_CS_AS, 'н')

почему-то возвращает ?


Потому что (как правильно выше написал iap)

select replace(N'h' collate Latin1_General_CS_AS, N'h' collate Latin1_General_CS_AS, N'н')
5 авг 19, 17:02    [21942248]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
Minamoto и iap, спасибо. Приставка N указывает программе, что на входе nvarchar?
6 авг 19, 09:19    [21942606]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
iap
Member

Откуда: Москва
Сообщений: 46983
Борис Гаркун
Minamoto и iap, спасибо. Приставка N указывает программе, что на входе nvarchar?
FAQ
6 авг 19, 09:34    [21942620]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
iap, спасибо. Получается с помощью N мы задаем default collation и одновременно допиской collate Latin1_General_CS_AS устанавливаем еще один collation. Зачем, кто из них побудит? :)
6 авг 19, 10:09    [21942647]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
*победит
6 авг 19, 10:10    [21942649]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
iap
Member

Откуда: Москва
Сообщений: 46983
Борис Гаркун
iap, спасибо. Получается с помощью N мы задаем default collation и одновременно допиской collate Latin1_General_CS_AS устанавливаем еще один collation. Зачем, кто из них побудит? :)
При чём здесь collation?
Если пишем литеральную строку, то встаёт вопрос: а какого она типа?
Чтобы избежать преобразование по умолчанию, когда имеем в виду юникодную строку,
пишем перед ней букву N, и сервер в момент чтения этой строки знает, что это - юникод.
Преобразование по умолчанию происходит не всегда корректно.
Символы юникода в MSSQL двухбайтные в отличие от строк ASCII.
Два байта на символ и один байт на символ - есть разница?
6 авг 19, 10:17    [21942655]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
iap, спасибо. А дописка collate Latin1_General_CS_AS для чего?
6 авг 19, 10:21    [21942658]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Борис Гаркун
iap, спасибо. А дописка collate Latin1_General_CS_AS для чего?

Чтобы указать параметры сравнения строк, а конкретно - Case Sensitive (CS в названии).
6 авг 19, 10:34    [21942670]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
Minamoto, спасибо!
6 авг 19, 11:18    [21942716]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Борис Гаркун
Member

Откуда: Лермонтов
Сообщений: 221
Здравствуйте!

Попробовал применить совет на практике:
SELECT 
	p.C_Name1
	, replace(Np.C_Name1 collate Latin1_General_CS_AS, Np.C_Name1 collate Latin1_General_CS_AS, N'н')
	, S.B_EE
FROM dbo.ED_Registr_Pts RP
JOIN dbo.SD_Subscr S -- ЛС
	ON S.F_Division	= RP.F_Division AND S.LINK = RP.F_Subscr
JOIN dbo.CD_Partners P -- Контрагент
	ON P.LINK = S.F_Partners
JOIN SV_Divisions d
	ON d.link = p.F_Division
WHERE
	p.C_Name1 LIKE '%h%'
	AND S.B_EE = 0

Возвращает ошибку вида "Не удалось привязать составной идентификатор "Np.C_Name1""
Если же N с пробелом:
SELECT 
	d.C_name
	, p.C_Name1
	, replace(N p.C_Name1 collate Latin1_General_CS_AS, N p.C_Name1 collate Latin1_General_CS_AS, N'н')
	, S.B_EE
FROM dbo.ED_Registr_Pts RP
JOIN dbo.SD_Subscr S	-- ЛС
		ON S.F_Division	= RP.F_Division AND S.LINK = RP.F_Subscr
JOIN dbo.CD_Partners P -- Контрагент
		ON P.LINK = S.F_Partners
JOIN SV_Divisions d
	ON d.link = p.F_Division
WHERE
	p.C_Name1 LIKE '%h%'
	AND S.B_EE = 0

то ошибка "Неправильный синтаксис около конструкции "p"."
Скажите, пожалуйста, как правильно применить ссылку на юникод(N)?
15 авг 19, 10:59    [21949877]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Guf
Member

Откуда: Новосибирск
Сообщений: 641
Борис Гаркун,

	, replace(p.C_Name1 collate Latin1_General_CS_AS, p.C_Name1 collate Latin1_General_CS_AS, N'н')

"N" нужен только у строковых констант, во всех остальных случаях он не нужен.
Одна из красных единиц, видимо, лишняя
15 авг 19, 11:23    [21949903]     Ответить | Цитировать Сообщить модератору
 Re: Чувствительность к регистру (функция replace)  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Борис Гаркун
Здравствуйте!

Попробовал применить совет на практике:
SELECT 
	p.C_Name1
	, replace(Np.C_Name1 collate Latin1_General_CS_AS, Np.C_Name1 collate Latin1_General_CS_AS, N'н')
	, S.B_EE
FROM dbo.ED_Registr_Pts RP
JOIN dbo.SD_Subscr S -- ЛС
	ON S.F_Division	= RP.F_Division AND S.LINK = RP.F_Subscr
JOIN dbo.CD_Partners P -- Контрагент
	ON P.LINK = S.F_Partners
JOIN SV_Divisions d
	ON d.link = p.F_Division
WHERE
	p.C_Name1 LIKE '%h%'
	AND S.B_EE = 0

Возвращает ошибку вида "Не удалось привязать составной идентификатор "Np.C_Name1""
Если же N с пробелом:
SELECT 
	d.C_name
	, p.C_Name1
	, replace(N p.C_Name1 collate Latin1_General_CS_AS, N p.C_Name1 collate Latin1_General_CS_AS, N'н')
	, S.B_EE
FROM dbo.ED_Registr_Pts RP
JOIN dbo.SD_Subscr S	-- ЛС
		ON S.F_Division	= RP.F_Division AND S.LINK = RP.F_Subscr
JOIN dbo.CD_Partners P -- Контрагент
		ON P.LINK = S.F_Partners
JOIN SV_Divisions d
	ON d.link = p.F_Division
WHERE
	p.C_Name1 LIKE '%h%'
	AND S.B_EE = 0

то ошибка "Неправильный синтаксис около конструкции "p"."
Скажите, пожалуйста, как правильно применить ссылку на юникод(N)?
N - это для строчных литералов.

Для приведения поля к юникоду надо использовать CAST или CONVERT:

SELECT 
	p.C_Name1
	, replace(Np.C_Name1 collate Latin1_General_CS_AS, CAST(p.C_Name1 as nvarchar(max)) collate Latin1_General_CS_AS, N'н')
	, S.B_EE
FROM dbo.ED_Registr_Pts RP
JOIN dbo.SD_Subscr S -- ЛС
	ON S.F_Division	= RP.F_Division AND S.LINK = RP.F_Subscr
JOIN dbo.CD_Partners P -- Контрагент
	ON P.LINK = S.F_Partners
JOIN SV_Divisions d
	ON d.link = p.F_Division
WHERE
	p.C_Name1 LIKE '%h%'
	AND S.B_EE = 0
15 авг 19, 11:24    [21949904]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить