问题
I am using MERGE
statement in order to insert XML
input to SQL Server database table. How to execute multiple conditions in WHEN MATCHED
block. Please refer the below code.
USING TableRelationship AS new
ON (new.TableRelationshipTypeID = old.TableRelationshipTypeID) AND old.ToRoleID = @RoleID
WHEN MATCHED THEN
UPDATE
SET old.FromRoleID = new.FromRoleID
-- Condition 2
-- Condition 3
Currently WHEN MATCHED
it only executes this old.FromRoleID = new.FromRoleID
line. How can I execute all 3 lines (-- Condition 2 and 3
) inside WHEN NOT MATCHED
condition.
Ex :
This is what I expect. WHEN MATCHED
I just want to update the old field (old.ThruDate = GETDATE()
) and insert a record to the same table. I cant separate those statements by a comma. SQL emits
Incorrect Syntax
MERGE INTO Party.TableRelationship AS old
USING TableRelationship AS new ON (new.TableRelationshipTypeID = old.TableRelationshipTypeID) AND old.ToRoleID = @RoleID
WHEN MATCHED THEN
UPDATE
SET old.ThruDate = GETDATE(),
INSERT (FromRoleID, ToRoleID, TableRelationshipTypeID)
VALUES (new.FromRoleID, new.ToRoleID, new.TableRelationshipTypeID);
Thank you.
回答1:
You could use INSERT over DML
to achieve it:
INSERT INTO tab_name(FromRoleID, ToRoleID, TableRelationshipTypeID)
SELECT FromRoleID, ToRoleID, TableRelationshipTypeID
FROM (
MERGE INTO Party.TableRelationship AS old
USING TableRelationship AS new
ON new.TableRelationshipTypeID = old.TableRelationshipTypeID
AND old.ToRoleID = @RoleID
WHEN MATCHED THEN
UPDATE SET old.ThruDate = GETDATE()
OUTPUT $action, FromRoleID, ToRoleID, TableRelationshipTypeID
) sub(action, FromRoleID, ToRoleID, TableRelationshipTypeID)
WHERE action = 'UPDATE';
Keep in mind that this method has some limitations more info: MS Connect
回答2:
This isn't what a merge statement is for. A merge statement either updates records if they already exist (WHEN MATCHED THEN), or it inserts records if they don't exist (WHEN NOT MATCHED THEN). It's not designed to insert records upon finding a match
(Side note: sqlserver merge statements can specify WHEN MATCHED twice, perhaps you'd use this with the aim that one of the matchings deletes records from the target that match some additional criteria, and the other specifies a list of columns to update if the additional logical test is false)
If you want to mix and match your inserting and updating when a record is matched, you'll need to use something else like a stored procedure or trigger that reacts to the update
Alternatively if you're just asking about how syntax of a merge statement, your insert directives need to be preceded by WHEN NOT MATCHED THEN INSERT ...
回答3:
You cannot do that - it is just plain not supported by SQL Server's MERGE
statement.
In the WHEN MATCHED
case, you can only do one UPDATE
(or DELETE
) statement - you cannot have multiple different statements after one another.
Check the official MSDN documentation for MERGE - it spells out what's possible and what's not supported in great detail:
Syntax:
MERGE
USING <table_source> ON <merge_search_condition>
[ WHEN MATCHED [ AND <clause_search_condition> ]
THEN <merge_matched> ] [ ...n ]
;
<merge_matched>::=
{ UPDATE SET <set_clause> | DELETE }
The MERGE statement can have at most two WHEN MATCHED clauses. If two clauses are specified, then the first clause must be accompanied by an AND clause. For any given row, the second WHEN MATCHED clause is only applied if the first is not. If there are two WHEN MATCHED clauses, then one must specify an UPDATE action and one must specify a DELETE action
回答4:
Those are not conditions, they are assignment clauses. You separate them by commas, as in update
:
USING TableRelationship AS new
ON (new.TableRelationshipTypeID = old.TableRelationshipTypeID) AND
old.ToRoleID = @RoleID
WHEN MATCHED THEN UPDATE
SET old.FromRoleID = new.FromRoleID,
<assignment 2>,
<assignment 3>;
来源:https://stackoverflow.com/questions/46141142/using-multiple-statements-in-when-matched