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