I have a table 'groups' which has some data in it:
groupid groupname grouptext
1 Cars Toyota
2 Cars BMW
3 Cars Renault
4 Bikes BMW
5 Bikes Yamaha
After that, I am the following SQL statements, in which I am trying to update the groups table using MERGE statement. What I want to do is to update the groups table with the data in XML. But I also want to delete all the entries in the table whose groupname is present in the XML. So for example after execution my table should look like this
groupid groupname grouptext
1 Cars Audi
4 Bikes BMW
5 Bikes Yamaha
6 Singers Lady Gaga
Since, there was groupname, and cars was in there, all the cars should be removed from the table. Now, when I use WHEN NOT MATCHED BY SOURCE AND clause I am getting this error:
Msg 5334, Level 16, State 2, Line 60
The identifier 's.groupname' cannot be bound. Only target columns and columns in the clause scope are allowed in the 'WHEN NOT MATCHED BY SOURCE' clause of a MERGE statement.
Msg 5334, Level 16, State 2, Line 61
The identifier 's.grouptext' cannot be bound. Only target columns and columns in the clause scope are allowed in the 'WHEN NOT MATCHED BY SOURCE' clause of a MERGE statement.
My question is, how can I achieve the desired result using the following code:
DECLARE @UpdateXml Xml = N'<groups>
<group>
<groupid>1</groupid>
<groupname>Cars</groupname>
<grouptext>Audi</grouptext>
</group>
<group>
<groupid>0</groupid>
<groupname>Singers</groupname>
<grouptext>Lady Gaga</grouptext>
</group>
</groups>';
DECLARE @hDoc INT;
EXEC sp_xml_preparedocument @hDoc OUTPUT, @UpdateXml;
MERGE INTO groups AS t
USING
(
SELECT groupid, groupname, grouptext
FROM OPENXML(@hdoc, '/groups/group', 1)
WITH
(
groupid INT 'groupid',
groupname VARCHAR(50) 'groupname',
grouptext VARCHAR(100) 'grouptext'
)
) AS source(groupid, groupname, grouptext)
ON
t.groupid = source.groupid AND
t.groupname = source.groupname
WHEN MATCHED THEN
UPDATE SET
groupname = source.groupname,
grouptext = source.grouptext
WHEN NOT MATCHED BY TARGET THEN
INSERT (groupname, grouptext)
VALUES (source.groupname, source.grouptext)
WHEN NOT MATCHED BY SOURCE AND
s.groupname = t.groupname AND
s.grouptext = t.grouptext
THEN
delete
;
The MERGE statement can have, at most, two WHEN MATCHED clauses. If two clauses are specified, the first clause must be accompanied by an AND <search_condition> clause. For any given row, the second WHEN MATCHED clause is only applied if the first isn't.
If you specify both the Update clause and the Insert clause, the MERGE statement can perform both INSERT and UPDATE operations on the target object. If you specify both the Delete clause and the Insert clause, the MERGE statement can perform both INSERT and DELETE operations on the target object.
SQL Server CHAR() Function The CHAR() function returns the character based on the ASCII code.
WHEN NOT MATCHED BY SOURCE clause in a MERGE
statement only accepts columns from the TARGET table. You can use a SubQuery, like:
WHEN NOT MATCHED BY SOURCE AND
t.groupname IN (SELECT s.groupname FROM table_name where xyz_condition)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With