Published:
Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.
Last week I posted about how to write re-runnable data update scripts for MySQL/MariaDB for use with version control to manage data in lookup/reference tables.
Unfortunately the "INSERT IGNORE" solution to this problem is specific to MySQL/MariaDB and will not work for us on Microsoft's SQL Server.
Solution MERGE INTO
While SQL Server does not have a direct equivalent of INSERT IGNORE, we can achieve the same result with some work utilizing the MERGE INTO statement. This statement is simply more verbose, but can be broken into five parts.
Using our previous countries lookup table as an example:
1. Specify target table
MERGE INTO
dbo.countries AS tgt
2. Specify source data (Table or values)
Note that we need to name the columns in our data here as we are supplying the data directly instead of reading from a table.
USING( VALUES
( 1 , 'Afghanistan', 'AF' )
,( 2 , 'Albania', 'AL' )
,( 3 , 'Algeria', 'DZ' )
,( 4 , 'Andorra', 'AD' )
,( 5 , 'Angola', 'AO' )
) AS src (
id
, name
, iso
)
3. Specify match condition
SQL Server will not assume to use the Primary Key so we explicitly specify the match condition
ON (tgt.id=src.id)
4. Match operation
If the match condition is met we define the update operation as follows
WHEN MATCHED THEN UPDATE SET
tgt.name=src.name
, tgt.iso=src.iso
5. Not Matched Operation
Finally we specify the insert operation for when the match condition is not met.
WHEN NOT MATCHED THEN INSERT (
id
, name
, iso
) VALUES (
src.id
, src.name
, src.iso
);
Final Solution
Putting these all together we get the following.
MERGE INTO
dbo.countries AS tgt
USING( VALUES
( 1 , 'Afghanistan', 'AF' )
,( 2 , 'Albania', 'AL' )
,( 3 , 'Algeria', 'DZ' )
,( 4 , 'Andorra', 'AD' )
,( 5 , 'Angola', 'AO' )
) AS src (
id
, name
, iso
)
ON (tgt.id=src.id)
WHEN MATCHED THEN UPDATE SET
tgt.name=src.name
, tgt.iso=src.iso
WHEN NOT MATCHED THEN INSERT (
id
, name
, iso
) VALUES (
src.id
, src.name
, src.iso
);
Note: The terminating semi-colon is required.
Reader Comments