Key words: merge compare columns
when we contact merge sql in ETL,
When we update some columns we should compare the value change or not.
We always write coalesce(columnname,valueifnull)<>coalesce(columnname,valueifnull)
But we should take care of the valueifnull, the value should not exist in tables and the data type
Should be right. Two points need to satisfy the requirements.
If you want to use sql to generate the sql automatically, you should know the column type for every column,
We can get this from database‘s meta data table, but we also need set the value if the column is null, this part
Will need a long case when , if not , we should have a configuration table to store this.
Another solution is :
Oracle:
Merge into target tar using (select * from source) as src
On tar.colx=src.colx…
When matched Update set col=src.col … where tar.col!=src.col or ( tar.col is null and src.col is not null) or (tar.col is not null and src.col is null)
It is long , if we execute it dynamically , the string may long exceed varchar2(4000);
Tar.col!=src.col (when the both columns are valid and not null)
Now, I think another expression to stand for not equal.
Not ( tar.col is null and src.col is null)
Sqlserver:
Merge into target tar using (select * from source) as src
On tar.colx=src.colx…
When matched and
(
tar.col<>src.col
Or not (tar.col is null and src.col is null)
Or ….
)
Update set coly=src.coly
…
You will notice that, there are some differences in merge implementation for oracle and sqlserver.
Slqserver is more powerful on this.
It support when matched and conditions but oracle not support this , but you can add the filter at where clause.
Just update what you want to update.
Another thing is sqlserver can judge the not matched case is caused by target table or source table.
When not matched by target table, insert data from source table.
When not matched by source talbe, just delete or do other actions.
On clause in merge is also need take care.
On tar.col=src.col and (tar.col is null and src.col is null)
Maybe is useful for your query.