Fix “Invalid column name ‘$action'” When Using the OUTPUT Clause in SQL Server (Error 207)

If you’re getting an error that reads “Invalid column name ‘$action’” in SQL Server, it could be that you’re using the $action argument of the OUTPUT clause for an operation that doesn’t support this argument.

Or it could be that the operation does support the argument, but you’re referencing it with the wrong syntax.

The $action argument can only be used with MERGE operations, and it must be done correctly.

To fix this issue, be sure to only use the $action argument in MERGE operations and to reference it with the correct syntax.

Example of Error

Here’s an example of code that produces the error:

INSERT INTO Customers (FirstName, LastName, Email)
OUTPUT 
    INSERTED.CustomerID,
    INSERTED.FirstName,
    INSERTED.LastName,
    $action
VALUES
    ('Rohit', 'Rooney', '[email protected]'),
    ('Selina', 'Bradey', '[email protected]'),
    ('Nelly', 'Nguyen', '[email protected]');

Output:

Msg 207, Level 16, State 1, Line 6
Invalid column name '$action'.

Here, I tried to use the $action argument in my OUTPUT clause, but I’m doing an INSERT operation. The $action argument isn’t supported in INSERT operations – only MERGE operations.

If this is happening to you, maybe you copied and pasted some OUTPUT code from a MERGE operation and you forgot to remove the $action part? Regardless, it shouldn’t be there.

We can also get the error while actually doing a MERGE:

MERGE TargetTable AS target
USING SourceTable AS source
ON target.ID = source.ID

WHEN MATCHED THEN
    UPDATE SET target.Name = source.Name, 
               target.Quantity = source.Quantity

WHEN NOT MATCHED BY TARGET THEN
    INSERT (ID, Name, Quantity) 
    VALUES (source.ID, source.Name, source.Quantity)

WHEN NOT MATCHED BY SOURCE THEN
    DELETE

OUTPUT 
    "$action" AS Operation,
    DELETED.ID AS OldID, 
    DELETED.Name AS OldName, 
    DELETED.Quantity AS OldQuantity,
    INSERTED.ID AS NewID, 
    INSERTED.Name AS NewName, 
    INSERTED.Quantity AS NewQuantity;

Output:

Msg 207, Level 16, State 1, Line 17
Invalid column name '$action'.

In this case I (incorrectly) surrounded the $action argument in double quotes, which produced the error.

Solution

First of all, we must be sure to only use the $action argument where it’s supported – in the MERGE statement.

So when it comes to our INSERT statement, all we need to do is remove the $action part:

INSERT INTO Customers (FirstName, LastName, Email)
OUTPUT 
    INSERTED.CustomerID,
    INSERTED.FirstName,
    INSERTED.LastName
VALUES
    ('Rohit', 'Rooney', '[email protected]'),
    ('Selina', 'Bradey', '[email protected]'),
    ('Nelly', 'Nguyen', '[email protected]');

Output:

CustomerID  FirstName  LastName
---------- --------- --------
1 Rohit Rooney
2 Selina Bradey
3 Nelly Nguyen

This time it worked.

As for the MERGE:

MERGE TargetTable AS target
USING SourceTable AS source
ON target.ID = source.ID

WHEN MATCHED THEN
    UPDATE SET target.Name = source.Name, 
               target.Quantity = source.Quantity

WHEN NOT MATCHED BY TARGET THEN
    INSERT (ID, Name, Quantity) 
    VALUES (source.ID, source.Name, source.Quantity)

WHEN NOT MATCHED BY SOURCE THEN
    DELETE

OUTPUT 
    $action AS Operation,
    DELETED.ID AS OldID, 
    DELETED.Name AS OldName, 
    DELETED.Quantity AS OldQuantity,
    INSERTED.ID AS NewID, 
    INSERTED.Name AS NewName, 
    INSERTED.Quantity AS NewQuantity;

Output:

Operation  OldID  OldName    OldQuantity  NewID  NewName    NewQuantity
--------- ----- --------- ----------- ----- --------- -----------
UPDATE 2 Product B 45 2 Product B 45
UPDATE 3 Product C 20 3 Product C 20
UPDATE 4 Product D 60 4 Product D 60

This one worked as expected too. All we did was remove the double quotes from the $action argument.