Перед тем, как дать вам код, я хочу сказать, что изменение этой конструкции, если вы можете!
База данных предназначена для таблиц и столбцов. Использование разделительной строки нарушает нормальную форму.
http://en.wikipedia.org/wiki/Database_normalization
Таким образом, я делаю это, намного сложнее манипулируют данные (D.M.L. ~ UPD, DEL, INS).
С этим ВНИМАНИЕ в сторону, я решил вашу проблему, используя следующий алгоритм.
1 - Create and load sample table with data.
2 - Choose a string split function, see article from Aaron Bertrand on choices.
3 - Split the string and store Items by Key, Column number order in a staging table 1
4 - Update the staging table 1. I did it for all column 2's.
However, there could be a where clause to do partial updates.
Also you could use update_flag to identify changed rows.
5 - Repackage the items as a string. I saved this step in staging table 2.
Can leverage update_flag to only packaged changed rows from staging table 1.
6 - Update the original table with new strings.
Вот пример кода для этого упражнения.
-- Just playing
use tempdb;
-- Drop the sample table
if OBJECT_ID('my_data') > 0
drop table my_data
go
-- Drop stage table 1
if OBJECT_ID('stage1') > 0
drop table stage1
go
-- Drop stage table 2
if OBJECT_ID('stage2') > 0
drop table stage2
go
-- Create sample table
create table my_data
(data_id INT, data_delimited_txt VARCHAR(100));
-- Add data
insert into my_data
values (1, '1,ABC,HZY'),(2, '2,DEF,XYZ'),(3, '3,ABC,MNP');
-- Show the data
select * from my_data;
go
-- http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings
-- String split function, save 2 stage1
select
d.data_id,
row_number() over (partition by d.data_id order by (select 0)) as row_id,
s.item
into
stage1
from
my_data d cross apply
msdb.dbo.SplitStrings_XML(d.data_delimited_txt, ',') as s
GO
-- Update second (col/val) in string
update stage1
set item = 'NEW VALUE'
where row_id = 2
go
-- Get updated string in stage2
select
data_id,
stuff(
(
SELECT ', ' + ISNULL(inner1.item,'')
FROM #stage as inner1
WHERE inner1.data_id = outer1.data_id
FOR XML PATH('')
) , 1, 2, '') as list_txt
into stage2
from stage1 as outer1
group by data_id
go
-- Update original table
update my_data
set data_delimited_txt = list_txt
from my_data m join stage2 s on m.data_id = s.data_id
go
-- Show the data
select * from my_data;
go
Я оставляю усовершенствование как флаг обновления (upd_flag) и любой элиминация шага для вас сделать.
Кроме того, функция разделения XML зависит от действительных данных XML. В выпуске продукта этого кода должна использоваться другая функция разделения, если это вызывает беспокойство.
Удачи.
Вопрос 1. Почему вы хранить ваши данные таким образом? Почему бы не сохранить всю эту CSV-информацию в разных столбцах? – Zane
Привет Зейн, Спасибо, что ответили. Это предварительно заполненная таблица, которую мы пытаемся обновить. У нас нет контроля над тем, как хранятся данные. – SillyCoda
Существуют методы в [http://www.sommarskog.se/arrays-in-sql-2005.html](http://www.sommarskog.se/arrays-in-sql-2005.html), чтобы разделить строка csv. Я предлагаю использовать процедуру CLR, чтобы вы могли разделить строку (String.Split), отредактировать третий элемент массива и объединить элементы массива (String.Join). –