C# 在表中插入并更新动态长度数组

C# 在表中插入并更新动态长度数组,c#,sql-server,arrays,stored-procedures,C#,Sql Server,Arrays,Stored Procedures,我的桌子是空的 (id int,property varchar) 假设我想插入{3',a,b,c'}。如何在存储过程中执行此操作? 表格条目将是: id property 3 a 3 b 3 c 另外,当我想用{3',ab,b,bg,ht'}更新我的id=3行时。此插入和更新操作的存储过程是什么?我的表条目应该是 id property 3 ab 3 b 3 bg 3 ht 第一个: insert into <tab

我的桌子是空的

(id int,property varchar)  
假设我想插入{3',a,b,c'}。如何在存储过程中执行此操作? 表格条目将是:

id property  
3   a  
3   b  
3   c  
另外,当我想用{3',ab,b,bg,ht'}更新我的id=3行时。此插入和更新操作的存储过程是什么?我的表条目应该是

id property  
3   ab  
3   b  
3   bg  
3   ht 
第一个:

insert into <tableName>(id, property) values(3, 'a');
insert into <tableName>(id, property) values(3, 'b');
insert into <tableName>(id, property) values(3, 'c');
第二期:

update <tableName> set property='ab' where property = 'a';
update <tableName> set property='bg' where property = 'c';
insert into <tableName>(id, property) values(3, 'ht');

现在,有一个问题:你确定这就是你的问题所需要的吗?通常,当我们调用一个列id时,我们希望它是一个标识符,也就是说,每行都是唯一的。这可能有点离题,但以防万一…

应该有一个唯一的id/主键。对任何唯一字段进行Profide,并根据该唯一字段更新记录。或者您可以使属性唯一或使id和属性对唯一。

如果我理解得很好,您可以执行类似的操作:

这只是一个伪代码,应该在存储过程中执行

如果这是正确的方法,您必须查看以下内容:

示例表:

create table yourtable (id int,property varchar(5))
该表的程序:

create procedure p_test
(
@id int, 
@prolist varchar(2000)
) as
begin
;with x as
(
  SELECT * FROM yourtable WHERE id = @ID
)
MERGE INTO 
x t1 
using 
(SELECT @id id, ltrim(t.c.value('.', 'VARCHAR(2000)')) property
FROM (
    SELECT x = CAST('<t>' + 
        REPLACE(@prolist, ',', '</t><t>') + '</t>' AS XML)
) a
CROSS APPLY x.nodes('/t') t(c))  t2 on t1.id = t2.id and t1.property = t2.property
when not matched then INSERT (id,property)   
VALUES(t2.id, t2.property) 
when matched 
THEN UPDATE SET t1.id = t2.id
WHEN NOT MATCHED BY SOURCE THEN DELETE
; 
end
结果:

id  property
3   b
3   c

id  property
3   b
3   c
3   a

id  property
3   c
3   a

id  property
4   g
3   c
3   a
4   h
编辑:

要更新新列,请使用此表:

create table yourtable (id int,property varchar(5), is_active bit default 1)
使用以下步骤:

alter procedure p_test
(
@id int, 
@prolist varchar(2000)
) as
begin
;with x as
(
  SELECT * FROM yourtable WHERE id = @ID
)
MERGE INTO 
x t1 
using 
(SELECT @id id, ltrim(t.c.value('.', 'VARCHAR(2000)')) property
FROM (
    SELECT x = CAST('<t>' + 
        REPLACE(@prolist, ',', '</t><t>') + '</t>' AS XML)
) a
CROSS APPLY x.nodes('/t') t(c))  t2 on t1.id = t2.id and t1.property = t2.property
when not matched then INSERT (id,property, is_active)   
VALUES(t2.id, t2.property, 1) 
when matched 
THEN UPDATE SET t1.id = t2.id, is_active = 1
WHEN NOT MATCHED BY SOURCE THEN 
UPDATE SET t1.is_active = 0
; 
end

:以上场景只是一个例子。数据将是动态的。@zooney我理解。然后尝试这些查询,它们应该可以工作。用您的表名替换并试一试。通常情况下是这样的。然而,这是完全有可能做到的OP想要的,虽然承认相当尴尬。版本是不正确的。它改变了最初的想法。应该是{3',a,b,c'}这意味着我的id是3,属性是{a,b,c}。每个属性项有三个表项。我尝试通过先删除匹配的行,然后插入新行来解决上述问题。我在寻找一种有效的方法来解决它。t-clausen.dk使用“合并”的回答非常适合我的问题。请重新打开我的问题,因为它也启发了sql中的合并方法。非常感谢。一个小问题,你能给出合并背后的想法吗。另外,如果“my_table”中有一列处于活动状态,则我希望将处于活动状态的列更新为0,而不是在源不匹配时删除该行。怎么做?:上面的问题有什么帮助吗?@zooney这是个好问题。我现在不知道。可能需要在存储的表达式中创建另一个表达式procedure@zooney创建了新版本的存储过程以满足您的新需求。请你再次接受我的回答
create table yourtable (id int,property varchar(5), is_active bit default 1)
alter procedure p_test
(
@id int, 
@prolist varchar(2000)
) as
begin
;with x as
(
  SELECT * FROM yourtable WHERE id = @ID
)
MERGE INTO 
x t1 
using 
(SELECT @id id, ltrim(t.c.value('.', 'VARCHAR(2000)')) property
FROM (
    SELECT x = CAST('<t>' + 
        REPLACE(@prolist, ',', '</t><t>') + '</t>' AS XML)
) a
CROSS APPLY x.nodes('/t') t(c))  t2 on t1.id = t2.id and t1.property = t2.property
when not matched then INSERT (id,property, is_active)   
VALUES(t2.id, t2.property, 1) 
when matched 
THEN UPDATE SET t1.id = t2.id, is_active = 1
WHEN NOT MATCHED BY SOURCE THEN 
UPDATE SET t1.is_active = 0
; 
end