2014-01-08 4 views
0

Я искал некоторую помощь в кодировании чего-то. Мы пытаемся обновить определенный столбец строки CSV, который у меня есть.SQL Server 2012 Обновить конкретный столбец в строке CSV

Вот скриншот, чтобы проиллюстрировать мою точку зрения: CSV Record

Столбец «DataRow» имеет строку CSV, что мне нужно изменить. Легко найти первый столбец с помощью CHARINDEX, но я не могу показаться, что код выходит за рамки этого. Я пытаюсь обновить третье значение в строке, в случае первой записи, будет «TM - Desert Wind Villas ..».

Есть ли у кого-нибудь предложения?

Большое спасибо!

+2

Вопрос 1. Почему вы хранить ваши данные таким образом? Почему бы не сохранить всю эту CSV-информацию в разных столбцах? – Zane

+0

Привет Зейн, Спасибо, что ответили. Это предварительно заполненная таблица, которую мы пытаемся обновить. У нас нет контроля над тем, как хранятся данные. – SillyCoda

+0

Существуют методы в [http://www.sommarskog.se/arrays-in-sql-2005.html](http://www.sommarskog.se/arrays-in-sql-2005.html), чтобы разделить строка csv. Я предлагаю использовать процедуру CLR, чтобы вы могли разделить строку (String.Split), отредактировать третий элемент массива и объединить элементы массива (String.Join). –

ответ

1

Перед тем, как дать вам код, я хочу сказать, что изменение этой конструкции, если вы можете!

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

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. В выпуске продукта этого кода должна использоваться другая функция разделения, если это вызывает беспокойство.

Удачи.

enter image description here

+0

Большое вам спасибо! Этот код работает именно так, как нужно! Я согласен с вами в столь необходимых изменениях дизайна, но это выходит за рамки наших возможностей; поскольку это внутренняя таблица, используемая системой ERP. Они используют эту таблицу для импорта CSV-файлов и манипулирования ими своими внутренними хранимыми процедурами. Мы хотели обновить значения в этой таблице, прежде чем процесс перейдет к следующим шагам. Опять же, это чрезвычайно ценная информация, которую вы предоставили, это, несомненно, сэкономит нам много времени. Еще раз, спасибо. – SillyCoda

+0

Мое удовольствие ... –

0

Я думаю, вы могли бы использовать where where что-то как следующее Я только SELECT (ing), но, очевидно, вы можете использовать инструкцию Update для обновления возвращенных данных. ...

Test Data

DECLARE @T TABLE (ID INT, Data VARCHAR(100)) 
INSERT INTO @T 
VALUES (1, '1,ABC,HZY'),(2, '2,DEF,XYZ'),(3, '3,ABC,MNP') 

SELECT * FROM @T 

╔════╦════════════╗ 
║ ID ║ Data ║ 
╠════╬════════════╣ 
║ 1 ║ 1,ABC,HZY ║ 
║ 2 ║ 2,DEF,XYZ ║ 
║ 3 ║ 3,ABC,MNP ║ 
╚════╩════════════╝ 

Запрос

SELECT * 
FROM @T 
WHERE (',' + Data + ',') LIKE '%MNP%' 

╔════╦════════════╗ 
║ ID ║ Data ║ 
╠════╬════════════╣ 
║ 3 ║ 3,ABC,MNP ║ 
╚════╩════════════╝ 
+0

Привет @ M.Ali, Большое вам спасибо за этот код. Насколько я понимаю, для того, чтобы обновить этот путь, нам нужно было бы узнать шаблон или символы в строке, которая должна быть обновлена, правильно ли это? В этом случае мы столкнулись с проблемой, так как мы не будем знать каждый раз, когда нам нужно обновить строку. Все, что мы уверены в позиции «столбца» в строке CSV; надеюсь, что имеет больше смысла? Еще раз благодарю вас за то, что вы нашли время, чтобы помочь мне в этом. Я ценю это. – SillyCoda

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