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

Откуда: Сидней
Сообщений: 1178
Добрый день,

Мне нужно изменить строки типа
1ABCD
1AC
1ACE
2A
2AC
на
1A,1B,1C,1D
1A,1C
1A,1C,1E
2A
2A,2C

Можно ли это сделать при помощи обычной функции REPACE или нужно писать цикл?

В общем как это проще всего сделать?

Спасибо.
4 июн 21, 04:19    [22331161]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
PizzaPizza
Member

Откуда:
Сообщений: 430
Roust_m,

если это надо сделать один раз, то сделайте это циклом, экспортируйте в текст, потом поправьте как надо и импортируйте обратно, натравите внешний скрипт обновляющий данные

если это надо делать постоянно, не храните данные так, используйте триггер или парсите это в приложении перед вставкой
4 июн 21, 04:35    [22331163]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
court
Member

Откуда:
Сообщений: 2335
Roust_m,

declare @t table (id integer identity, txt varchar(100))

insert into @t (txt) values
('1ABCD'),
('1AC'),
('1ACE'),
('2A'),
('2AC')

;with cte as (
	select
		t.id,
		t.txt,
		a.number,
		a.ch
	from @t t
	cross apply (select v.number, substring(t.txt, 1+v.number, 1) as ch from master..spt_values v 
                          where v.number < len(t.txt) and v.type = 'P') a
)
select
	t1.id,
	t1.ch + t2.ch as xz
from cte t1 inner join cte t2 on t1.id=t2.id 
where t1.number = 0 and t2.number <> 0
order by t1.id, t2.number 

idxz
11A
11B
11C
11D
21A
21C
31A
31C
31E
42A
52A
52C
4 июн 21, 07:17    [22331169]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
court
Member

Откуда:
Сообщений: 2335
даа, и "склеить" обратно
declare @t table (id integer identity, txt varchar(100))

insert into @t (txt) values
('1ABCD'),
('1AC'),
('1ACE'),
('2A'),
('2AC')

;with cte as (
	select
		t.id,
		t.txt,
		a.number,
		a.ch
	from @t t
	cross apply (select v.number, substring(t.txt, 1+v.number, 1) as ch from master..spt_values v 
                           where v.number < len(t.txt) and v.type = 'P') a
)
select
	t1.id,
	string_agg(t1.ch + t2.ch, ',') within group(order by t2.number) as xz
from cte t1 inner join cte t2 on t1.id=t2.id 
where t1.number = 0 and t2.number <> 0
group by t1.id
order by t1.id

idxz
11A,1B,1C,1D
21A,1C
31A,1C,1E
42A
52A,2C


Сообщение было отредактировано: 4 июн 21, 07:20
4 июн 21, 07:27    [22331171]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
declare @t table (id integer identity, txt varchar(100));

insert into @t (txt) values
('1ABCD'),
('1AC'),
('1ACE'),
('2A'),
('2AC')

declare @n int = ( select max(len(txt)) from @t );

while @n > 2 begin

  update @t set txt = stuff(txt, @n, 0, ',' + left(txt, 1) )
    where len(txt) >= @n;

  set @n = @n - 1;

end;

select * from @t;
4 июн 21, 08:18    [22331178]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
MaksK
Member

Откуда:
Сообщений: 11
Roust_m,

CREATE FUNCTION dbo.Replacetxt (@TXT AS NVARCHAR(50))
RETURNS NVARCHAR(250)
AS
BEGIN
	DECLARE @Text NVARCHAR(250)= ''

	SELECT
		@Text= REPLACE(REPLACE(@Text + QUOTENAME(C), '[', ''), ']', '')
	FROM
		(
		SELECT T, IIF(R= 1, A+B,','+A+B) C
		FROM
			(
				SELECT
					ROW_NUMBER() OVER (ORDER BY @TXT) R
					,SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)) T
					,SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)) A, SUBSTRING(REPLACE(@TXT, SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)), ''),number,1) B
				FROM MASTER.dbo.spt_values
				WHERE TYPE='P' AND NUMBER BETWEEN 1 AND LEN(REPLACE(@TXT, SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)), ''))
			) D
		) TB

	RETURN @Text
END



declare @t table (id integer identity, txt varchar(100));

insert into @t (txt) values
('1ABCD'),
('1AC'),
('1ACE'),
('2A'),
('2AC')

SELECT ID, dbo.Replacetxt(TXT)
FROM @T



Модератор: Используйте tag SRC


Сообщение было отредактировано: 4 июн 21, 14:55
4 июн 21, 14:51    [22331398]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8690
Roust_m,

автор
как это проще всего сделать


Проще всего создать несколько CLR функций для работы с регулярными выражениями, в инете полно описаний.
4 июн 21, 15:54    [22331455]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
Владислав Колосов
Roust_m,

автор
как это проще всего сделать


Проще всего создать несколько CLR функций для работы с регулярными выражениями, в инете полно описаний.

Глупо.
Эти функции производят массу лишней вычислительной работы.

ЗЫ. Зря, что-ли, мелкософт не вводит в T-SQL такие "функции".
4 июн 21, 16:53    [22331497]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
+ Пиписькомер :)
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort, nocount on;
go

CREATE or alter FUNCTION dbo.Replacetxt (@TXT AS NVARCHAR(50))
RETURNS NVARCHAR(250)
AS
BEGIN
	DECLARE @Text NVARCHAR(250)= ''

	SELECT
		@Text= REPLACE(REPLACE(@Text + QUOTENAME(C), '[', ''), ']', '')
	FROM
		(
		SELECT T, IIF(R= 1, A+B,','+A+B) C
		FROM
			(
				SELECT
					ROW_NUMBER() OVER (ORDER BY @TXT) R
					,SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)) T
					,SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)) A, SUBSTRING(REPLACE(@TXT, SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)), ''),number,1) B
				FROM MASTER.dbo.spt_values
				WHERE TYPE='P' AND NUMBER BETWEEN 1 AND LEN(REPLACE(@TXT, SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)), ''))
			) D
		) TB

	RETURN @Text
END
go

declare @r table (descr varchar(50), elapsed_time_ms int);

drop table if exists #t;
create table #t (id integer identity primary key, txt varchar(100));

insert into #t (txt)
select
 d.s
from
 (select top (50000) a.number from master.dbo.spt_values a cross join master.dbo.spt_values b) c cross apply
 (values ('1ABCD'), ('1AC'), ('1ACE'), ('2A'), ('2AC'), ('3ABCDEFGHIJKLMNOPQRSTUVWXYZ')) d(s);

declare @dt datetime2 ;

begin tran;

set @dt = sysdatetime();
declare @n int = ( select max(len(txt)) from #t );

while @n > 2 begin

  update #t set txt = stuff(txt, @n, 0, ',' + left(txt, 1) )
    where len(txt) >= @n;

  set @n = @n - 1;

end;

insert into @r
select 'cycle by aleks222', datediff(ms, @dt, sysdatetime());

rollback;

begin tran;

set @dt = sysdatetime();

update #t
 set
  txt = stuff(RegexpReplaceWrapper(substring(txt, 2, cast(0x7fffffff as int)), '(.{1})', ',' + left(txt, 1) + '$1', 'default'), 1, 1, '')
from
 #t;

insert into @r
select 'RegexpReplace wrapper', datediff(ms, @dt, sysdatetime());

rollback;

begin tran;

set @dt = sysdatetime();

with x as
(
 select
  t.txt, b.txt_new
 from
  #t t cross apply
  (
   select
    string_agg(a.s, ',') within group (order by a.rn)
   from
    (
     select top (len(t.txt) - 1)
      row_number() over (order by 1/0) as rn,
      left(t.txt, 1) + substring(t.txt, row_number() over (order by 1/0) + 1, 1)
     from
      master.dbo.spt_values
    ) a(rn, s)
  ) b(txt_new)
)
update x
 set
  txt = txt_new;

insert into @r
select 'split and string_agg b invm', datediff(ms, @dt, sysdatetime());

rollback;

begin tran;

set @dt = sysdatetime();

;with cte as (
	select
		t.id,
		t.txt,
		a.number,
		a.ch
	from #t t
	cross apply (select v.number, substring(t.txt, 1+v.number, 1) as ch from master..spt_values v 
                           where v.number < len(t.txt) and v.type = 'P') a
),
s as
(
 select
 	t1.id,
 	string_agg(t1.ch + t2.ch, ',') within group(order by t2.number) as xz
 from cte t1 inner join cte t2 on t1.id=t2.id 
 where t1.number = 0 and t2.number <> 0
 group by t1.id
)
update t
 set
  txt = s.xz
from
 s join
 #t t on t.id = s.id;

insert into @r
select 'by court', datediff(ms, @dt, sysdatetime());

rollback;

begin tran;

set @dt = sysdatetime();

update #t set txt = dbo.Replacetxt(txt);

insert into @r
select 'scalar function by MaksK', datediff(ms, @dt, sysdatetime());

rollback;

select * from @r order by elapsed_time_ms;
go

drop function dbo.Replacetxt;
go

descrelapsed_time_ms
split and string_agg b invm1231
cycle by aleks2223482
RegexpReplace wrapper4347
by court13766
scalar function by MaksK15643
4 июн 21, 18:46    [22331570]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
Если соревноваться "на скорость" - надо немного индексов дописать.
4 июн 21, 18:52    [22331574]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
----

Сообщение было отредактировано: 4 июн 21, 18:48
4 июн 21, 18:56    [22331580]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
aleks222
Если соревноваться "на скорость" - надо немного индексов дописать.
Например?
4 июн 21, 19:36    [22331595]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8690
aleks222,

речь шла о "проще", а не "быстро". Проще - регулярные выражения, вне конкуренции.
4 июн 21, 21:32    [22331647]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
Владислав Колосов
aleks222,

речь шла о "проще", а не "быстро". Проще - регулярные выражения, вне конкуренции.

Иллюзия.
У каждого "свое регулярное выражение".
Сколько раз я сталкивался с необходимостью править - стока раз и отгребал немерянный геморрой.
5 июн 21, 05:41    [22331688]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
invm
aleks222
Если соревноваться "на скорость" - надо немного индексов дописать.
Например?

доп. поле N = длине исходного текста
+ кластерный индекс по этому полю
+ where N <= @n
5 июн 21, 05:43    [22331689]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
aleks222
доп. поле N = длине исходного текста
+ кластерный индекс по этому полю
+ where N <= @n
Такой индекс добавит в план расходов на устранение потенциальной hallowin problem. Так что для данного конкретного случая возможно даже ухудшение, а не улучшение производительности.
5 июн 21, 09:37    [22331702]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Roust_m
Member

Откуда: Сидней
Сообщений: 1178
aleks222
Если соревноваться "на скорость" - надо немного индексов дописать.


Не, скорость не нужна, ибо там всего 2-3 тысячи записей. Нужна простота, чтобы поменьше кода и багов было.
7 июн 21, 03:12    [22332066]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8690
Roust_m,

при использовании регулярных выражений это будет всего одна строка, что-то вроде написанного выше (выражение можно упростить):

declare @txt varchar(100) = '1ASDF';
select STUFF(dbo.RegexReplace(@txt, '.', ',' + left(@txt, 1) + '$0'), 1, 4, '');
7 июн 21, 11:01    [22332138]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
Владислав Колосов
Roust_m,

при использовании регулярных выражений это будет всего одна строка, что-то вроде написанного выше (выражение можно упростить):

declare @txt varchar(100) = '1ASDF';
select STUFF(dbo.RegexReplace(@txt, '.', ',' + left(@txt, 1) + '$0'), 1, 4, '');


Проблема не в "одной строке" - проблема в голове.

while @n > 2 begin update @t set txt = stuff( txt, @n, 0, ',' + left(txt, 1) )  where len(txt) >= @n; set @n = @n - 1; end;
7 июн 21, 12:01    [22332176]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
Доработанный "писькомер", с учетом пожелания алекса и замечания Владислава Колосова
+
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort, nocount on;
go

CREATE or alter FUNCTION dbo.Replacetxt (@TXT AS NVARCHAR(50))
RETURNS NVARCHAR(250)
AS
BEGIN
	DECLARE @Text NVARCHAR(250)= ''

	SELECT
		@Text= REPLACE(REPLACE(@Text + QUOTENAME(C), '[', ''), ']', '')
	FROM
		(
		SELECT T, IIF(R= 1, A+B,','+A+B) C
		FROM
			(
				SELECT
					ROW_NUMBER() OVER (ORDER BY @TXT) R
					,SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)) T
					,SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)) A, SUBSTRING(REPLACE(@TXT, SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)), ''),number,1) B
				FROM MASTER.dbo.spt_values
				WHERE TYPE='P' AND NUMBER BETWEEN 1 AND LEN(REPLACE(@TXT, SUBSTRING(@TXT, 0, PATINDEX('%[^0-9]%', @TXT)), ''))
			) D
		) TB

	RETURN @Text
END
go

drop table if exists #t;

create table #t (id integer identity, txt varchar(100), l as len(txt) persisted);

insert into #t (txt)
select
 d.s
from
 (select top (50000) a.number from master.dbo.spt_values a cross join master.dbo.spt_values b) c cross apply
 (values ('1ABCD'), ('1AC'), ('1ACE'), ('2A'), ('2AC'), ('3ABCDEFGHIJKLMNOPQRSTUVWXYZ')) d(s);

--create clustered index IX_t__l on #t(l);

begin tran;

declare @n int = ( select max(l) from #t );

while @n > 2 begin

  update/*cycle by aleks222*/ #t set txt = stuff(txt, @n, 0, ',' + left(txt, 1) )
    where l >= @n;

  set @n = @n - 1;

end;

rollback;

begin tran;

update /*RegexpReplace wrapper*/ #t
 set
  txt = stuff(RegexpReplace(substring(txt, 2, cast(0x7fffffff as int)), '.', ',' + left(txt, 1) + '$0'), 1, 1, '')
from
 #t;

rollback;

begin tran;

with x as
(
 select
  t.txt, b.txt_new
 from
  #t t cross apply
  (
   select
    string_agg(a.s, ',') within group (order by a.rn)
   from
    (
     select top (len(t.txt) - 1)
      row_number() over (order by 1/0) as rn,
      left(t.txt, 1) + substring(t.txt, row_number() over (order by 1/0) + 1, 1)
     from
      master.dbo.spt_values
    ) a(rn, s)
  ) b(txt_new)
)
update /*split and string_agg by invm*/ x
 set
  txt = txt_new
option
 (maxdop 1);

rollback;

begin tran;

with x as
(
 select
  t.txt, b.txt_new
 from
  #t t cross apply
  (
   select
    string_agg(a.s, ',') within group (order by a.rn)
   from
    (
     select top (len(t.txt) - 1)
      row_number() over (order by 1/0) as rn,
      left(t.txt, 1) + substring(t.txt, row_number() over (order by 1/0) + 1, 1)
     from
      master.dbo.spt_values
    ) a(rn, s)
  ) b(txt_new)
)
update /*split and string_agg by invm (optimization spool+sort off)*/ x
 set
  txt = txt_new
option
 (maxdop 1, queryruleoff BuildSpool);

rollback;

begin tran;

;with cte as (
	select
		t.id,
		t.txt,
		a.number,
		a.ch
	from #t t
	cross apply (select v.number, substring(t.txt, 1+v.number, 1) as ch from master..spt_values v 
                           where v.number < len(t.txt) and v.type = 'P') a
),
s as
(
 select
 	t1.id,
 	string_agg(t1.ch + t2.ch, ',') within group(order by t2.number) as xz
 from cte t1 inner join cte t2 on t1.id=t2.id 
 where t1.number = 0 and t2.number <> 0
 group by t1.id
)
update /*by court*/ t
 set
  txt = s.xz
from
 s join
 #t t on t.id = s.id;

rollback;

begin tran;

update /*scalar function by MaksK*/ #t set txt = dbo.Replacetxt(txt);

rollback;

with r as
(
 select
  a.descr
 from
  (
   values
    ('split and string_agg by invm'), ('by court'), ('RegexpReplace wrapper'), ('cycle by aleks222'), ('scalar function by MaksK'),
    ('split and string_agg by invm (optimization spool+sort off)')
  ) a(descr)
),
qs as
(
 select top (1) with ties
  r.descr, qs.execution_count, qs.total_worker_time, qs.total_elapsed_time, qs.creation_time,
  a.statement_text, cast(qp.query_plan as xml) as query_plan
 from
  sys.dm_exec_query_stats qs join
  sys.dm_exec_cached_plans cs on cs.plan_handle = qs.plan_handle cross apply
  sys.dm_exec_sql_text(qs.sql_handle) st cross apply
  sys.dm_exec_text_query_plan(qs.plan_handle, qs.statement_start_offset, qs.statement_end_offset) qp cross apply
  (
   select substring(st.text, (qs.statement_start_offset/2)+1,   
          ((case qs.statement_end_offset  
             when -1 then datalength(st.text)  
             else qs.statement_end_offset  
            end - qs.statement_start_offset)/2) + 1)
 ) a(statement_text) join
 r on a.statement_text like '%/*' + r.descr + '*/%'
 order by
  row_number() over (partition by r.descr order by qs.creation_time desc)
)
select
 *
from
 qs
order by
 total_elapsed_time
option
 (recompile);
go

drop function dbo.Replacetxt;
go

Без кластерного индекса
descrexecution_counttotal_worker_timetotal_elapsed_time
split and string_agg by invm155707365574050
split and string_agg by invm (optimization spool+sort off)160299076031316
by court11072529110728791
RegexpReplace wrapper11264266312759471
scalar function by MaksK12042599620428520
cycle by aleks222252653689226551510

С кластерным индексом
descrexecution_counttotal_worker_timetotal_elapsed_time
split and string_agg by invm128853732886588
split and string_agg by invm (optimization spool+sort off)136568943658163
by court184948228508147
RegexpReplace wrapper11057879710723925
cycle by aleks222251095822610958685
scalar function by MaksK11720619317207736
7 июн 21, 12:10    [22332182]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
Что-то у тебя показания сильно гуляют? Не, есть, канешно, и стабильные герои.
7 июн 21, 12:16    [22332191]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8690
invm,

мой эксперимент показал, что при использовании CLR функции, которая содержит только RETURN input_paramert невозможно получить результат при вставке в новую таблицу лучше, чем 400 мсек в среднем. Т.е. это теоретический предел, который можно достигнуть специализированной функцией для разбора и формирования новой строки. Вашим же примером достигается результат 200мсек.

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

Если требуется "простота", то CLR функция - это компромисс по производительности.
7 июн 21, 12:25    [22332201]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
aleks222, Владислав Колосов

Это намеки на подтасовку?

Ну так скрипт и результаты опубликованы.
CLR-функция использовалась такая
    private static readonly Dictionary<String, RegexOptions> OptionsDictionary = new Dictionary<String, RegexOptions>()
    {
        {"None", RegexOptions.None},
        {"IgnoreCase", RegexOptions.IgnoreCase},
        {"Multiline", RegexOptions.Multiline},
        {"CultureInvariant", RegexOptions.CultureInvariant},
        {"Compiled", RegexOptions.Compiled},
        {"ECMAScript", RegexOptions.ECMAScript},
        {"ExplicitCapture", RegexOptions.ExplicitCapture},
        {"IgnorePatternWhitespace", RegexOptions.IgnorePatternWhitespace},
        {"RightToLeft", RegexOptions.RightToLeft},
        {"Singleline", RegexOptions.Singleline}
    };

    private static RegexOptions ParseOptions(SqlString AOptionsString)
    {
        if (AOptionsString.IsNull)
            return DefaultOptions;
        
        RegexOptions AOptions = RegexOptions.None;
        RegexOptions x;

        String[] s = AOptionsString.Value.Split(new String[] {",", "|"}, StringSplitOptions.RemoveEmptyEntries);
        foreach (String o in s)
            if (OptionsDictionary.TryGetValue(o, out x))
                AOptions |= x;

        return AOptions;
    }

   [SqlFunction(IsDeterministic = true, IsPrecise = true)]
    public static SqlString RegexpMatch(SqlString AText, SqlString APattern, SqlString AReplacementPattern, SqlString AOptions)
    {
        if (APattern.IsNull || AText.IsNull)
            return SqlString.Null;

        var m = Regex.Match(AText.Value, APattern.Value, ParseOptions(AOptions));
        return AReplacementPattern.IsNull ? m.Value : m.Result(AReplacementPattern.Value);
    }

Сервер
Microsoft SQL Server 2019 (RTM-CU10) (KB5001090) - 15.0.4123.1 (X64) 
	Mar 22 2021 18:10:24 
	Copyright (C) 2019 Microsoft Corporation
	Developer Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 19041: )


Так что теперь можете экспериментировать самостоятельно.
7 июн 21, 13:21    [22332248]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
invm
aleks222, Владислав Колосов
Это намеки на подтасовку?
Так что теперь можете экспериментировать самостоятельно.



Не, дарагой, мне лень.
Я и без твоих изысков представляю недостатки и достоинства вариантов.
7 июн 21, 13:28    [22332259]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
aleks222
Я и без твоих изысков представляю недостатки и достоинства вариантов.
Ну тогда бы не предлагал кластерный индекс :)
7 июн 21, 13:39    [22332271]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8690
invm,

нет, причем здесь намёки, я писал о вставке результата в новую таблицу. Вариант с обновлением работает приблизительно вчетверо хуже.
7 июн 21, 14:10    [22332299]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
Владислав Колосов,

Хотите сказать, что insert и update работают с CLR по-разному?
7 июн 21, 14:18    [22332304]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
aleks222
Member

Откуда:
Сообщений: 1414
invm
aleks222
Я и без твоих изысков представляю недостатки и достоинства вариантов.
Ну тогда бы не предлагал кластерный индекс :)


Дык оно и без кластерного, внезапно, стала хуже.
Чудесные явления виртуальной природы.
7 июн 21, 14:23    [22332312]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
aleks222
Дык оно и без кластерного, внезапно, стала хуже.
Не внезапно.
1. В таблицу добавился столбец
2. Времена стали браться из серверной статистики.

Возможно я где-то и накосячил, но не увидел где.
7 июн 21, 14:56    [22332339]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
declare @t table (id integer identity, txt varchar(100))

insert into @t (txt) values
('1ABCD'),
('1AC'),
('1ACE'),
('2A'),
('2AC')

select 
	txt = vals.n + left(repl.s, len(repl.s) - 2)
from @t AS t
cross apply(values(left(txt, 1), right(txt, len(txt) -1))) AS vals(n, s)
cross apply(values(convert(varchar(200), convert(varbinary(200), convert(nvarchar(100), vals.s))))) AS bin(s) 
cross apply(values(replace(bin.s collate latin1_general_bin, char(0x00), ',' + vals.n))) AS repl(s)
7 июн 21, 15:07    [22332349]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
invm
Member

Откуда: Москва
Сообщений: 9772
Shakill, это грязный хак :)
7 июн 21, 16:15    [22332400]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8690
invm
Владислав Колосов,

Хотите сказать, что insert и update работают с CLR по-разному?


Нет, UPDATE работает медленнее в любых примерах по сравнению с INSERT приблизительно в 4 раза. Может это связано с параллельной вставкой, не проверял.
7 июн 21, 16:45    [22332424]     Ответить | Цитировать Сообщить модератору
 Re: Замена символов в строке  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
invm, но довольно быстрый и без цикла ) есть, конечно, некоторые ограничения
7 июн 21, 16:52    [22332430]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Microsoft SQL Server Ответить