When target and source values are the same does Merge Command update? - sql

Wasn't really able to find the answer anywhere for this, trying to understand when using the Merge command, if there is a row in my target table that is identical to my source table if it will update the values anyways from the source table.
In other words I have the following tables:
Will the source table still run an update on the target table in the above situation?
What I'm trying to do, if the target table equals source table, do nothing.
Only apply the update/insert/delete functions if there is a true difference between the tables.
AND BONUS POINTS, IF POSSIBLE, only run an update on the specific column that is different not the entire row.
I'm afraid that currently when the "matched" condition is met, it will update the values regardless if they are in fact the same.
Now, I understand even if the values are updated they wont be incorrect, but I'm trying to keep track of true adjustments to table via insert/update/delete operations.
MERGE target_table USING source_table
ON merge_condition
WHEN MATCHED
THEN update_statement
WHEN NOT MATCHED
THEN insert_statement
WHEN NOT MATCHED BY SOURCE
THEN DELETE;

It appears it still is marked as updated in terms of log activity, but the data itself doesn't update (minus a few situations noted on the link below). Please see this question on the DBA Stack Exchange
DBA StackExchange - Non-Updating Updates
The Impact of Non-Updating Updates

Related

Can I prevent duplicate data in bigquery?

I'm playing with BQ and I create a table and inserted some data. I reinserted it and it created duplicates. I'm sure I'm missing something, but is there something I can do to ignore it if the data exists in the table?
My use case is I get a stream of data from various clients and sometimes their data will include some data they previously already sent(I have no control on them submitting).
Is there a way to prevent duplicates when certain conditions are met? The easy one is if the entire data is the same but also if certain columns are present?
It's difficult to answer your question without a clear idea of the table structure, but it feels like you could be interested in the MERGE statement: ref here.
With this DML statement you can perform a mix of INSERT, UPDATE, and DELETE statements, hence do exactly what you are describing.

Merge into CTE vs Merge into Table

I have a question regarding performance of Merge into CTE against Merge into Table.
My scenario is as below:
I am facing an issue in existing stored procedure which is responsible to merge data into table from staging source table. The target table has around 20 million records.
Merging is performed into CTE which is subset of target table filtered on date range. This date range matches with the date range of source table. However, due to incorrect logic implementation, the source table sometimes contain data out of the date range as well. This results in unwanted & duplicate data insertion into target table.
The logic in the stored procedure is now corrected and this change is expected to fix the issue. But, to be sure that, such kind of issue never occur again, is it advisable to merge into table instead of CTE? Considering the size of the target table (~20M rows), what will be the performance trade-off? What are the pros and cons to merge into table considering performance point of view?
Microsoft advises against using CTEs as targets.
Use the WITH clause to filter out rows from
the source or target tables. This method is similar to specifying
additional search criteria in the ON clause and may produce incorrect
results. We recommend that you avoid using this method or test
thoroughly before implementing it.
See for more details: https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15#join-best-practices
From performance standpoint I do not think it would make any difference. I have never tested this though.

SQL Server Triggers Order of Execution

I was wondering if I might ask a top level SQL Server triggers question - more specifically with regards to the order of processing.
Take the following example: on insert into Table A, I have a trigger that fires and if a condition is met, it updates a given column #1 on the 'just inserted' row of Table A.
Table A also has another trigger that checks for updates to column #1, and if a condition is met, then a new row is inserted into Table B.
Table B also has a trigger set to check on insert and if a certain condition is met, then column #2 is updated in Table A.
Updates to column #2 are also caught in another trigger which can then insert into yet another Table C.
I'm sorry if I have lost you in there... this was not by my design!
I am getting some strange error messages about "Invalid Column names" in triggers totally unrelated to the work process above and I cant help but think that there is simply too much 'triggerness' going on across the same tables for SQL Server to keep up - but I don't know enough about the order of trigger execution and how they might be more tightly controlled to guess.
I am hoping my question is not too vague and can yield some helpful feedback. Most importantly I want to know if the above should 'just work' or are there any specific considerations to make when too'ing and fro'ing triggers to the same table.

How can I update lookup fields in a row with randomly chosen rows from the related table in access SQL?

I have a table with 5 fields that are all the same. They each can hold a reference to a row from another table with relationships. I want to update all of these fields at the same time on a row, but with a randomly selected row from the table for each field (with no duplicates). I am not sure how in access SQL you can update a lookup/relationship field like this. Any advice is greatly appreciated.
Simple answer is that you can't, not as it appears you would like to anyway. The closest thing possible would be to create an Insert query with parameters, and then feed in your 5 values using VBA. Since you will have to use VBA anyway, you may as well go the whole hog and conduct the entire process with Recordsets.
But that's not the fiddly part, (relatively speaking) selecting your source values is. What you will need to do is open a Recordset on your source table, and hook it up to your random-no-duplicates logic in order to select your 5 record references, then you open up a Recordset on your destination table, and drop them in the appropriate fields.
This tutorial will get you started on Recordsets: http://www.utteraccess.com/wiki/index.php/Recordsets_for_Beginners

Logging the results of a MERGE statement

I have 2 tables: A temporary table with raw data. Rows in it may be repeating (more then 1 time). The second is the target table with actual data (every row is unique).
I'm transfering rows using a cursor. Inside the cursor I use a MERGE statement. How can I print to the console using DBMS_OUTPUT.PUT_LINE which rows are updated and which are deleted?
According to the official documentation there is no such feature for this statement.
Are there any workaround?
I don't understand why you would want to do this. The output of dbms_output requires someone to be there to look at it. Not only that it requires someone to look through all of the output otherwise it's pointless. If there are more than say 20 rows then no one will be bothered to do so. If no one looks through all the output to verify but you need to actually log it then you are actively harming yourself by doing it this way.
If you really need to log which rows are updated or deleted there are a couple of options; both involve performance hits though.
You could switch to a BULK COLLECT, which enables you to create a cursor with the ROWID of the temporary table. You BULK COLLECT a JOIN of your two tables into this. Update / delete from the target table based on rowid and according to your business logic then you update the temporary table with a flag of some kind to indicate the operation performed.
You create a trigger on your target table which logs what's happening to another table.
In reality unless it is important that the number of updates / deletes is known then you should not do anything. Create your MERGE statement in a manner that ensures that it errors if anything goes wrong and use the error logging clause to log any errors that you receive. Those are more likely to be the things you should be paying attention to.
Previous posters already said that this approach is suspicious, both because of the cursor/loop and the output log for review.
On SQL Server, there is an OUTPUT clause in the MERGE statement that allows you to insert a row in another table with the $action taken (insert,update,delete) and any columns from the inserted or deleted/overwritten data you want. This lets you summarize exactly as you asked.
The equivalent Oracle RETURNING clause may not work for MERGE but does for UPDATE and DELETE.