SQL Merge with inserting into the third table - sql-server

I want to create a merge that will compare two tables and insert not matched values into another third table or table variable
something like this:
MERGE Assets AS target
USING (#id, #name)FROM Sales AS source (id, name) ON (target.id = SOURCE.id)
WHEN MATCHED THEN
UPDATE SET target.Status = #status, target.DateModified = SYSUTCDATETIME()
WHEN NOT MATCHED THEN
INSERT INTO #tableVar (id, name, status, dateModified)
VALUES (#id, #name, #status, SYSUTCDATETIME())
Can this be done or are there other methods?

You just cannot do this. MERGE operates on two tables only - source and target.
For your requirement, you need to e.g. use a CTE (Common Table Expression) to find the rows that don't match - and insert those into the third table.
Something like:
;WITH NonMatchedData AS
(
-- adapt this as needed - just determine which rows match your criteria,
-- and make sure to return all the columns necessary for the subsequent INSERT
SELECT (columns)
FROM dbo.SourceTable
WHERE ID NOT IN (SELECT DISTINCT ID FROM dbo.TargetTable)
)
INSERT INTO dbo.ThirdTable(Col1, Col2, ....., ColN)
SELECT Col1, Col2, ....., ColN
FROM NonMatchedData

You CAN do this very easily...
You can wrap the MERGE statement within a INSERT INTO FROM:
http://technet.microsoft.com/en-us/library/bb510625.aspx#sectionToggle2
-OR-
You can do it directly within the merge statement:
Quick example:
WHEN NOT MATCHED THEN
DELETE
OUTPUT Deleted.* INTO dbo.MyTable;
This will insert the non-matches into your existing destination table. You can use the Updated, Inserted, Deleted v-tables to direct data other places.

Related

MERGE into first table based on id of second table if not matched

I have two tables table_1 and table_2. After inserting some data into table_1(insert not in the example below), it gives Auto_Increment ID to table_1. Then I need to put this new generated ID into table_2 in NOT MATCHED section.
I am trying to use T-SQL's MERGE, to UPDATE table if data already exists (if matched) or INSERT INTO table if there is no such data(not matched), but in second case insert by using one column selected from another table.
Here is what I have already tried:
MERGE
INTO table_2 WITH (HOLDLOCK) AS target
USING (SELECT
'42' AS person_id
,2 AS skill_id
) AS source
(person_id,skill_id )
ON (target.person_id = source.person_id
AND target.skill_id = source.skill_id)
WHEN MATCHED
THEN UPDATE
SET skill_lvl=4,already_have=0
WHEN NOT MATCHED
--section below doesn't work,because insert inside MERGE has to be without select (?)
THEN INSERT (person_id, skill_id, skill_lvl,already_have)
SELECT 42, id,3,1 FROM table_1;
Not matched section gives me an error that he waits values or default, but it seems kind of tricky to select with values or default.
Edit_1
Insert query to table_1 (happens before previous MERGE. Both MERGES within one loop):
MERGE
INTO table_1 WITH (HOLDLOCK) AS target
USING (SELECT
'skill_1' AS skill_name
) AS source
(skill_name)
ON (target.skill_name = source.skill_name)
WHEN NOT MATCHED
THEN INSERT (category_id,skill_name) values (0,'skill_1');
this query in the loop, compares skill_names, if name is not inside this table_1, it inserts this value. Then compare next skill_name and so on. ID's are generating automatically after inserting.

How to Auto increment column when using merge and in not matching case - SQL Server

Want to add a incremental number in MERGE when the NOT MATCHED case.
It only allows to write insert statements, I tried to set the value using the MAX() function too, but adds the same number to all the records.
What is expected
MERGE #targetTable AS [target]
USING #sourceTable AS [source] ON [target].key = [source].key
WHEN MATCHED
UPDATE ROWS
WHEN NOT MATCHED THEN
INSERT (id, Name)
VALUES ([incremented_id], source.Name);
Note : Table already have some records in it.
Any help would be appreciated
Try to get max ID from the table and then add it to this parameter. With this select you will be creating a new id of every row that is inserted. Something like this should work
declare #root int = 64895
WHEN MATCHED
UPDATE ROWS
WHEN NOT MATCHED THEN
INSERT (id, Name)
VALUES( ((#root - 1) + ROW_NUMBER() over(order by ID)), source.Name);

Output insert and table values when doing insert into

I'm inserting into a table in MS SQL Server 2008 (it's rather a copy of values from the same table) and want to get the output values for the insert. I want to get the id value of the select statement (t.id in the example below), the INSERTED.id works just fine
create table tmp.tbl_inserted (fromId int, toId int)
INSERT INTO mytable (name)
OUTPUT t.id, INSERTED.id INTO tmp.tbl_inserted
SELECT t.name FROM mytable t
Thanks in advance
You can't do it directly from an INSERT:
from_table_name
Is a column prefix that specifies a table included in the FROM clause of a DELETE, UPDATE, or MERGE statement that is used to specify the rows to update or delete.
Note that INSERT isn't mentioned.
What you have to do instead is cheat and use a MERGE:
MERGE INTO mytable m
USING (name,id FROM mytable) t ON 1=0
WHEN NOT MATCHED THEN INSERT (name) VALUES (t.name)
OUTPUT t.id, INSERTED.id INTO tmp.SizeCurveGroup_inserted
;

SQL Server query - how to insert selected values into another table

Here's what I am trying to do.
This is the select statement
select Id
from tblUsersPokemons
where UserId = 1 and PokemonPlace = 'bag'
Now I want to insert those returned Ids into another table like this:
foreach all returned Ids
insert into tblNpcBattleUsersPokemons values (Id, 1)
How can I do that ?
Like this:
insert into tblNpcBattleUsersPokemons
select Id, 1 from tblUsersPokemons where UserId=1 and PokemonPlace='bag'
This can be done in a single sql call
insert into tblNpcBattleUsersPokemons (id, [whatever the name of the other column is])
select Id, 1 from tblUsersPokemons where UserId=1 and PokemonPlace='bag'
I've used the longhand here because it does not make any assumption about the ordering of columns in the destination table, which can change over time and invalidate your insert statement.
You can insert the set retrieved by a SELECT into another existing table using the INSERT...SELECT syntax.
For example:
INSERT INTO tblNpcBattleUsersPokemons (Id, Val) -- not sure what the second column name was
SELECT Id FROM tblUsersPokemons WHERE UserID = 1 and PokemonPlace='bag';

SQL Insert into Select failure due to one of the set of records

I am trying to insert a set of records into a table using
Insert into tbl1 Select * from tbl
One of the records failed due to check constrain in tbl1. But i want to insert the other records which have passed the check constraint and others i want to catch them as exception. Could someone please help.
In that case, you need to be more selective about your SELECT - exclude those rows that are trouble from your selection:
INSERT INTO dbo.tbl1(Col1, Col2, ...., ColN)
SELECT Col1, Col2, ....., ColN
FROM dbo.tbl
WHERE (some condition here to exclude those rows that don't match the `CHECK` constraint.....)

Resources