3

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 
asked Jan 7, 2014 at 11:59
3
  • the edition is not right. It changed the initial idea. Should be {3, 'a, b, c'} Commented 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. Commented 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. Commented Jan 8, 2014 at 8:58

4 Answers 4

3

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
answered Jan 7, 2014 at 12:44
Sign up to request clarification or add additional context in comments.

3 Comments

thanks a lot. One small query , can u please give the idea behind the merging. Also if 'my_table' had a column is_active and instead of deleting the row when not matched by source ,I want to update is_active to 0. How to do it?
:Any help on above query?
@zooney that is a good question. I don't know right now. It may be necessary to make another expression inthe stored procedure
1

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...

answered Jan 7, 2014 at 12:03

2 Comments

:well above scenario is just an example. the data would be dynamic.
@zooney I understand. Then try those queries, they should work. Substitute your table name for <tableName> and give it a go.
0

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.

answered Jan 7, 2014 at 12:05

1 Comment

This is the case normally. However it is perfectly possible to do what the OP wants, though admittedly quite awkward.
0

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

answered Jan 7, 2014 at 12:25

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.