2016-04-19 4 views
1

У меня есть сценарий, в котором я получаю данные как разделитель запятой. Например, данные в таблице аналогичны приведенным ниже.SQL значения, разделенные запятой, операция dml

EmpID Location Active 
109  2  1  
109  3  1  
109  4  1 

Теперь я получаю данные как EMPID 109, Location (1,2,5). Что мне нужно сделать, это вставить 1,5, поскольку они не существуют в табличных данных, Update 2, как это существует в таблице. Установите 3,4 в таблице на активный 0, поскольку они существуют в табличных данных, но не существуют в данных, которые мы получили. Я пытаюсь сделать все это в одном sql вместо использования нескольких sql.

+0

Вы можете сделать это с помощью [MERGE] (https://msdn.microsoft.com/en-GB/library/bb510625.aspx). –

+0

MERGE - только часть решения здесь. Поскольку вы получаете список значений с разделителями, вам сначала нужно разобрать или разбить это на значения. Вот большой ресурс для этого шага. http://sqlperformance.com/2012/07/t-sql-queries/split-strings Тогда вы можете использовать MERGE для выполнения upsert, который вы ищете. Но будьте осторожны ... использование MERGE для upserts может вызвать проблемы. https://connect.microsoft.com/SQLServer/feedback/details/723696/basic-merge-upsert-causing-deadlocks –

ответ

0

Проблема заключается в анализе данных CSV. Я взял подход к его синтаксическому анализу с помощью XML и затем использовал merge для обработки обновляющей таблицы. В приведенном ниже примере я создаю таблицу с именем e и назначил некоторые данные CSV @CSV. Код ниже - это целый рабочий пример.

-- Just creating a working space 
create table e (
    EmpID int, 
    Location int, 
    Active int 
) 

insert e values (109, 2, 1), (109, 3, 1), (109, 4, 1) 
declare @csv varchar(100) = '1,2,5' -- Assuming everything is nice integer data 
select 'Before merge', * from e 

merge e as target 
using (select distinct e.EmpID 
      , m.n.value('.[1]', 'varchar(8000)') Location 
     from (select e.* 
        , cast('<xmlroot><rowdata>' + replace(@csv, ',', '</rowdata><rowdata>') + '</rowdata></xmlroot>' as xml) x 
       from e) e 
     cross apply x.nodes('/xmlroot/rowdata') m(n)) as source 
    on target.EmpID = source.EmpID and target.Location = source.Location 
when matched then 
    update set Active = 1 
when not matched then 
    insert (EmpId, Location, Active) 
    values (source.EmpID, source.Location, 1) 
when not matched by source then 
    update set Active = 0 
; 
select 'After merge', * from e 
+0

Получение ошибок в m.n.value и x.nodes в редакторе sql в ssms. x.nodes как недопустимый объект и m.n.value неоднозначное имя столбца или отсутствующее имя функции. – user3038399

+0

Вы сначала попытались скопировать весь блок кода? (Я успешно выполнил его в SSMS.) Также, какую версию SQL Server вы используете? – user212514

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