Need help with the Merge statement

11,491

Solution 1

I believe you have to alias your your source data like so:

USING (select SOR.identity_column, 
   CASE  WHEN left(SOR.FPARTNO, 2) = 'BL' 
   THEN 'Blue'        
   WHEN left(SOR.FPARTNO, 2) = 'RD' 
   THEN 'Red'        
   ELSE 'White'      
   END from Sorels AS SOR) **AS SOR** ON  (SORe.fkey_id = SOR.identity_column)

Solution 2

INSERT (SORe.fkey_id, SORe.Color) 

should read:

INSERT (fkey_id, Color) 

Columns in the insert list can only refer to the target table. The parser doesn't expect to see a table alias there, and doesn't know how to resolve it.

If it sees "column1", it knows it belongs to the target table. It sees "table1.column1", it doesn't know what "table1" means, since "table1" as a token is out of scope.

Share:
11,491
DavidStein
Author by

DavidStein

I'm a Data Warehouse Architect who utilizes the Microsoft BI Stack.

Updated on July 31, 2022

Comments

  • DavidStein
    DavidStein over 1 year

    I want to update a table called Sorels_ext from a table called Sorels. The link between them is the fkey_id of Sorels_ext equals the identity_column of the Sorels table. This is my first attempt at a Merge statement and I'm trying to learn the syntax.

    MERGE Sorels_ext AS SORe
    USING (select SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END from Sorels AS SOR)
    ON  (SORe.fkey_id = SOR.identity_column)
    
    WHEN MATCHED THEN
      UPDATE SET SORe.fkey_id = SOR.identity_column, SORe.Color = select SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END
    WHEN NOT MATCHED THEN
      INSERT (SORe.fkey_id, SORe.Color) VALUES (SOR.identity_column, SORe.Color = select SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END);
    

    When I run this, I get the following error:

    Error 10/22/2009 1:38:51 PM 0:00:00.000 SQL Server Database Error: Incorrect syntax near the keyword 'ON'. 46 0

    *** ADDED INFO ******

    After the first fix suggested, the code is as follows:

        MERGE Sorels_ext AS SORe
    USING (select SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END from Sorels) AS SOR
    ON  (SORe.fkey_id = SOR.identity_column)
    
    WHEN MATCHED THEN
      UPDATE SET SORe.fkey_id = SOR.identity_column, SORe.Color = CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END
    WHEN NOT MATCHED THEN
      INSERT (SORe.fkey_id, SORe.Color) VALUES (SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END);
    

    Now I get the following error:

    Error 10/22/2009 2:03:29 PM 0:00:00.000 SQL Server Database Error: The insert column list used in the MERGE statement cannot contain multi-part identifiers. Use single part identifiers instead. 55 0

    ******* ADDED MORE INFO ****** After adjustments from suggestions, I have the following:

        MERGE Sorels_ext AS SORe
    USING (select SOR1.identity_column, CASE
            WHEN left(SOR1.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR1.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END as colors from Sorels as SOR1 ) as SOR 
    ON  (SORe.fkey_id = SOR.identity_column)
    
    WHEN MATCHED THEN
      UPDATE SET SORe.fkey_id = SOR.identity_column, SORe.Color = CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END
    WHEN NOT MATCHED THEN
      INSERT (fkey_id, Color) VALUES (SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END);
    

    I get the error:

    Error 10/22/2009 2:46:51 PM 0:00:00.000 SQL Server Database Error: Invalid column name 'FPARTNO'. 56 0

    What am I doing wrong?

    **** I GOT IT!!! *****

    MERGE Sorels_ext AS SORe
    USING (select SOR.identity_column, CASE
            WHEN left(SOR.FPARTNO, 2) = 'BL' THEN 'Blue'
            WHEN left(SOR.FPARTNO, 2) = 'RD' THEN 'Red'
            ELSE 'White'
          END as colors from Sorels as SOR) SOR1  
    ON  (SORe.fkey_id = SOR1.identity_column)
    
    WHEN MATCHED THEN
      UPDATE SET SORe.fkey_id = SOR1.identity_column, SORe.Color = SOR1.colors
    WHEN NOT MATCHED THEN
      INSERT (fkey_id, Color) VALUES (SOR1.identity_column, SOR1.colors);
    
  • OMG Ponies
    OMG Ponies over 14 years
    Agreed. The OP example is using a table alias that doesn't exist on that JOIN.
  • DavidStein
    DavidStein over 14 years
    I just edited it again with that correction and the new error. I really appreciate your patience.
  • rfonn
    rfonn over 14 years
    I agree with Peter on this one.
  • Peter Radocchia
    Peter Radocchia over 14 years
    Columns in the insert list can only refer to the target table, so the parser doesn't expect to see a table alias there, wouldn't know how to resolve it. It sees "column1", it knows it belongs to the target table. It sees "table1.column1", it doesn't know what "table1" means. "table1" is out of scope, so to speak.
  • DavidStein
    DavidStein over 14 years
    I updated it again. I am using the aliases to make things easier and more clear and they seem to be having the opposite effect.