2016-11-03 2 views
0

Есть некоторые объекты, закодированные как строки: значения и сохраненные в таблице, я хотел бы увеличить порядковый номер всех объектов, что является одним полем в объекте.Увеличение числа в строке

Например:

ID Value 
-------------------------- 
504 s:0;d:n;e:test; 
506 s:1;d:y;e:branch; 
507 s:2;d:y;e:; 

Я хотел бы изменить их:

ID Value 
-------------------------- 
504 s:1;d:n;e:test; 
506 s:2;d:y;e:branch; 
507 s:3;d:y;e:; 

Есть простой способ сделать это?

+0

означает число всегда предстают перед d и ы – TheGameiswar

+0

Числа всегда одна цифра? – Buddi

ответ

6

Есть ли простой способ сделать это?

Нет, не совсем.

Вы можете найти позиции s: и d:, а затем использовать их для извлечения числа между ними, увеличить его на единицу и вернуть обратно туда, где он принадлежит.

declare @T table 
(
    ID int, 
    Value varchar(50) 
); 

insert into @T values 
(504, 's:0;d:n;e:test;'), 
(506, 's:1;d:y;e:branch;'), 
(507, 's:2;d:y;e:;'); 

select T.ID, 
     stuff(T.Value, P.S, P.D - P.S - 1, S.Value) as NewValue 
from @T as T 
    cross apply (values(charindex('s:', T.Value) + 2, 
         charindex('d:', T.Value))) as P(S, D) 
    cross apply (values(substring(T.Value, P.S, P.D - P.S - 1) + 1)) as S(Value) 

версия, где вы найдете ; после s: вместо d: как предложил Эрику в комментарии.

select T.ID, 
     stuff(T.Value, S.Pos, SEnd.Pos - S.Pos, V.NewValue) as NewValue 
from @T as T 
    cross apply (values(charindex('s:', T.Value) + 2)) as S(Pos) 
    cross apply (values(charindex(';', T.Value, S.Pos))) as SEnd(Pos) 
    cross apply (values(substring(T.Value, S.Pos, SEnd.Pos - S.Pos) + 1)) as V(NewValue) 
+0

Я думаю, что получить charindex ';' вместо 'd:' соответствует фактическому использованию поля, поскольку это 'key: value;'. d не обязательно появляться сразу после s. – Eric

+0

@ Эрик Да, это было бы лучше. Я обновил ответ. –

0
DECLARE @val nvarchar(200) 

SET @val = 's:1;d:y;e:branch;' 

SELECT 's:' + CONVERT(nvarchar(100), CONVERT(INT, SUBSTRING(@val, charindex(':', @val) + 1, charindex(';', @val) - charindex(':', @val) -1)) + 1) + SUBSTRING(@val, charindex(':', @val),1000) 

Вы можете использовать то, что в запросе на SELECT в операторе UPDATE для изменения таблицы значений

+0

Предположили, что столбец <1000 символов. При необходимости увеличьте это значение –

0

Используя раскол строковые функции здесь: Split strings the right way – or the next best way

declare @string varchar(max) 
set @string='504 s:0;d:n;e:test;' 

;with cte as(select * from 
[dbo].[SplitStrings_Numbers] 
(@string,':')) 
select b.item+1 from cte c 
cross apply 
(select * from [dbo].[SplitStrings_Numbers](c.item,';')) b 
where isnumeric(b.item)=1 
0

Это объясняет пустые или нецелые значения; он будет игнорировать их в том случае, если они не могут быть увеличены на единицу.

-- Build Test Data 
IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test 
CREATE TABLE #test (ID INT, Value VARCHAR(100)) 

INSERT #test 
VALUES 
(504,'s:0;d:n;e:test;'), 
(506,'s:1;d:y;e:branch;'), 
(507,'s:2;d:y;e:;'), 
(508,'s:;d:y;e:;'), 
(509,'s:xyz;d:y;e:;'); 

-- Update S: values 
WITH sVals AS 
(
    SELECT ID, Value, TRY_PARSE(SUBSTRING(Value,CHARINDEX('s:',Value)+2,CHARINDEX(';',Value,CHARINDEX('s:',Value))-(CHARINDEX('s:',Value)+2)) AS INT) AS sVal 
    FROM #test AS t 
) 
UPDATE s 
SET Value = IIF(sVal IS NOT NULL, STUFF(Value,CHARINDEX('s:',Value)+2,CHARINDEX(';',Value,CHARINDEX('s:',Value))-(CHARINDEX('s:',Value)+2),sVal+1), Value) 
FROM sVals AS s 

-- Check the results 
SELECT * 
FROM #test 
0

Вы можете, как показано ниже:

DECLARE @val VARCHAR(100) = 's:12;d:n;e:test;' 
SELECT REPLACE(@val, ':' + SUBSTRING(@val, 3, PATINDEX('%;d:%', @val) - 3) + ';', ':' + CAST(SUBSTRING(@val, 3, PATINDEX('%;d:%', @val) - 3)+ 1 AS VARCHAR(MAX)) + ';') 

Результат: s:13;d:n;e:test;

Смежные вопросы