My table is
(id int,property varchar)
Suppose I want to insert {3, 'a, b, c'}
. How can I do it in a stored procedure?
The table entry would be:
id property
3 a
3 b
3 c
Also when i want to update my id=3
row by {3, 'ab, b, bg, ht'}
. What would be the stored procedure for this insert and update operation? My table entries should become
id property
3 ab
3 b
3 bg
3 ht
-
the edition is not right. It changed the initial idea. Should be {3, 'a, b, c'}Thiago C. S Ventura– Thiago C. S Ventura2014年01月07日 12:11:52 +00:00Commented Jan 7, 2014 at 12:11
-
It means my id is 3 and property is {a,b,c}. three table entries for each property item.zooney– zooney2014年01月07日 12:14:48 +00:00Commented Jan 7, 2014 at 12:14
-
I tried solving the above problem by first deleting the matched rows and then inserting the new rows. I was looking for an efficient approach to solve it. And answer by t-clausen.dk by use of 'merging' is quite appropriate for my problem.Kindly re-open my problem as it enlightens the approach of merging in sql as well.zooney– zooney2014年01月08日 08:58:06 +00:00Commented Jan 8, 2014 at 8:58
4 Answers 4
sample table:
create table yourtable (id int,property varchar(5))
Procedure for that table:
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
Testing:
exec p_test 3, 'b,c'
select * from yourtable
exec p_test 3, 'a,b,c'
select * from yourtable
exec p_test 3, 'a,c'
select * from yourtable
exec p_test 4, 'g,h'
select * from yourtable
Result:
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
EDIT:
in order to update a new column use this table:
create table yourtable (id int,property varchar(5), is_active bit default 1)
Use this procedure:
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
3 Comments
First one:
insert into <tableName>(id, property) values(3, 'a');
insert into <tableName>(id, property) values(3, 'b');
insert into <tableName>(id, property) values(3, 'c');
Second issue:
update <tableName> set property='ab' where property = 'a';
update <tableName> set property='bg' where property = 'c';
insert into <tableName>(id, property) values(3, 'ht');
And now, a question: are you sure this is what your problem needs? Usually, when we call a column id
we want it to be an identifier, that is, unique for each row. This may be a little bit off topic, but just in case...
2 Comments
There should be an id/primary key which will be unique. Profide any unique field and update records on the base of that unique field. Or you can make property unique or pair of id and property unique.
1 Comment
If I understood well, you could do something similar to this:
Insert INTO @tempTable
SELECT 3, * FROM dbo.splitstring('a,b,c,d')
It's just a pseudocode and you should do it inside your stored procedure.
If this is the right approach you have to take a look at this: T-SQL split string
Comments
Explore related questions
See similar questions with these tags.