I use system-versioned tables in my SQL Server database, which has a number of tables with parent/child relationships. I am writing a stored procedure to update a set of parent/child tables using parameters supplied to the procedure.
With system-versioned tables, a new row will be created in the history table whenever an UPDATE command is run, even if none of the values have changed. To avoid creating numerous rows in my history table that are identical to rows in my temporal table, I would like this SP to only update a table when a value supplied by a parameter is different from a value that already exists in the table row.
Based on similar questions I've seen, I know I could include something in the WHERE statement to do this (i.e., WHERE @Param <> [Value]); however, I will be dealing with a large number of different tables and values, so I was hoping to find a more scalable solution.
I'm not a fan of using
@Param <> ColumnNamesyntax for something like this; if either value isNULLthen this expression will resolve the UNKNOWN, which isn't TRUE, and so the row isn't affected. The more complete version would be:For a lot of
NULLable columns that becomes very long.In newer versions of SQL Server you can use
IS DISTINCT FROMinstead, which will treat an expression likeNULL IS DISTINCT FROM 1as TRUE andNULL IS DISTINCT FROM NULLas FALSE.This, much like the solution you have, involves a lot of
ORclauses:An alternative method I quite like is to use an
EXCEPTorINTERSECTin a(NOT) EXISTS), andSELECTthe parameters in one and the columns in the other. This would look something like this:If all the columns and parameters have the same value then a row won't be returned in the subquery, and so the
EXISTSreturns FALSE and the row isn't updated. LikeIS DISTINCT FROM, this will handleNULLvalues, asSELECT NULL EXCEPT SELECT NULL;will result in no returned rows.