在源和不匹配时合并



我有一个表"groups",其中包含一些数据:

groupid     groupname       grouptext
1           Cars            Toyota
2           Cars            BMW
3           Cars            Renault
4           Bikes           BMW
5           Bikes           Yamaha

之后,我将编写以下SQL语句,其中我将尝试使用MERGE语句更新groups表。我想做的是用XML中的数据更新groups表。但我也想删除表中XML中存在组名的所有条目。例如,在执行之后,我的表应该看起来像这个

groupid     groupname       grouptext
1           Cars            Audi
4           Bikes           BMW
5           Bikes           Yamaha
6           Singers         Lady Gaga

既然有组名,而且车在里面,所有的车都应该从表上删除。现在,当我使用when NOT MATCHED BY SOURCE AND子句时,我会得到以下错误:

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.

我的问题是,如何使用以下代码来实现所需的结果:

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
;
MERGE语句中的WHEN NOT MATCHED BY SOURCE子句只接受TARGET表中的列。您可以使用SubQuery,例如:
WHEN NOT MATCHED BY SOURCE AND
    t.groupname IN (SELECT s.groupname FROM table_name where xyz_condition)

最新更新