Roll-back last UPDATE SQL query in SQL Server 2014 - sql

I have accidentally executed the query:
UPDATE TableName
SET Name='Ram'
How can I undo this change?

Before running update, or deletes especially always test them. For an delete put the statement into a select block.
SELECT COUNT(NAME)
FROM TableName
WHERE
And make sure the number of records returned match what you are wanting to delete. FOr an update it is a little more envolved. You will have to use a transaction.
BEGIN TRANSACTION
UPDATE TableName
SET Name = 'Ram'
SELECT *
FROM TableName
WHERE Name = 'Ram'
--Rollback Transaction
--Commit Transaction
Based on what you did in the transaction just run the first part leaving commit and rollback commented out then the select will let you validate everything worked correctly then if it is what you want highlight and run just the COMMIT without the comments if it isn't what you wanted then highlight an run just the ROLLBACK without comments to undo it and try again. Hope this helps in the future.

Related

How to lock the transaction untill single query completes its execution for not getting deadlock error

I have the following code in which I have doubt.
Update Statement on Table 1
Update Statement on Table 2
Select Statement which include both the Table 1
Now above code will return to the application. means it is get all function for the application.
I am getting deadlock error in the application frequently.
I have hundred of users which is fetching the same table at a time.
So I have to make sure that untill the completion of update statement select statement will not fire OR how to lock the update statement.
One more doubt that if suppose I am updating the one row & another user has tried to select that table then will he get the deadlock.
(User was trying to select another row which was not in the update statement.)
what will happen for this scenario.
Please help me.
Thanks in advance
You should use transaction,
BEGIN TRANSACTION [Tran1]
BEGIN TRY
Update Statement on Table 1
Update Statement on Table 2
Select Statement which include both the Table 1
COMMIT TRANSACTION [Tran1]
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1]
END CATCH
GO
If you want nobody to update/delete the row, I would go with the UPDLOCK on the SELECT statement. This is an indication that you will update the same row shortly, e.g.
select #Bar = Bar from oFoo WITH (UPDLOCK) where Foo = #Foo;

Select for Update Lock

I want to prevent simultaneous update(by multiple sessions) for my record in my stored procedure.
1.I am , using SELECT FOR UPDATE statement for the particular row , which i want to update it.
This will lock the record.
I am updating this record now and then commit it. So the lock is released and now the record is available for another user/session to work on with.
However , when i try to run the procedure , i am finding the simultaneous update is happening , means SELECT FOR UPDATE not working fine.
Pls provide some suggestions.
Sample Code is below :
IF THEN
// do something
ELSIF THEN
BEGIN
SELECT HIGH_NBR INTO P_NBR FROM ROUTE
WHERE LC_CD = <KL_LCD> AND ROUTE_NBR = <KL_ROUTE_NBR>
FOR UPDATE OF HIGH_NBR ;
UPDATE ROUTE SET HIGH_NBR = (HIGH_NBR + 1)
WHERE LC_CD = <KL_LCD> AND ROUTE_NBR = <KL_ROUTE_NBR>;
COMMIT;
END;
END IF;
In multiple user environment , i am observing the SELECT FOR UPDATE lock is not happening.
I just tested the scenario with two different computers (Sessions). Here is what i have did.
From One computer , executed SELECT FOR UPDATE statement -- Locking a row.
From Another computer , execute an UPDATE statement for the same record.
Update did not happen and the Sql execution of update statement is not completed , even after a long time.
When will be the lock released , if we issue an SELECT FOR UPDATE for a record.
first of all you need to set auto commit false before starting the query.
and to check your code is working you can use two Java treads with a cyclic barrier
and also you should add timestamps on you code to check the time of the code being reached.

Sql delete not appearing to work

I am running delete sql in Managment Studio 2008 and it indicated to me the sql has worked....but it hasnt.
For example
select count(*) from MyTable where [MYkey] =24
returns 1
delete from MyTable where [MYkey] = 24
Rows Affected 1
But if I immediately run the first statement again, the record is still there. If I try an update statement, that works. I am seeing this behaviour on all tables in the database.
I had a few issues with the Transaction log being full a few days ago, I change the recovery model to simple. Could this be related? If so what do I need to do?
Try this -
BEGIN TRANSACTION;
delete from MyTable where [MYkey] = 24;
COMMIT TRANSACTION;

Deadlock on query that is executed simultaneously

I've got a stored procedure that does the following (Simplified):
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE #intNo int
SET #intNo = (SELECT MAX(intNo) + 1 FROM tbl)
INSERT INTO tbl(intNo)
Values (#intNo)
SELECT intNo
FROM tbl
WHERE (intBatchNumber = #intNo - 1)
COMMIT TRANSACTION
My issue is that when two or more users execute this at the same time I am getting deadlocks. Now as I understand it the moment I do my first select in the proc this should create a lock in tbl. If the second procedure is then called while the first procedure is still executing it should wait for it to complete right?
At the moment this is causing a deadlock, any ideas?
The insert query requires a different lock than the select. The lock for select blocks a second insert, but it does not block a second select. So both queries can start with the select, but they both block on the other's insert.
You can solve this by asking the first query to lock the entire table:
SET #intNo = (SELECT MAX(intNo) + 1 FROM tbl with (tablockx))
^^^^^^^^^^^^^^^
This will make the second transaction's select wait for the complete first transaction to finish.
Make it simpler so you have one statement and no transaction
--BEGIN TRANSACTION not needed
INSERT INTO tbl(intNo)
OUTPUT INSERTED.intNo
SELECT MAX(intNo) + 1 FROM tbl WITH (TABLOCK)
--COMMIT TRANSACTION not needed
Although, why aren't you using IDENTITY...?

Which SQL Read TRANSACTION ISOLATION LEVEL do I want for long running insert?

I have a long running insert transaction that inserts data into several related tables.
When this insert is running, I cannot perform a select * from MainTable. The select just spins its wheels until the insert is done.
I will be performing several of these inserts at the same/overlapping time. To check that the information is not inserted twice, I query the MainTable first to see if an entry is there and that its processed bit is not set.
During the insert transaction, it flips the MainTable processed bit for that row.
So I need to be able to read the table and also be able to tell if the specific row is currently being updated.
Any ideas on how to set this up in Microsoft SQL 2005? I am looking through the SET TRANSACTION ISOLATION LEVEL documentation.
Thank you,
Keith
EDIT: I do not think that the same insert batch will happen at the same time. These are binary files that are being processed and their data inserted into the database. I check that the file has not been processed before I parse and insert the data. When I do the check, if the file has not been seen before I do a quick insert into the MainTable with the processed bit set false.
Is there a way to lock the row being updated instead of the entire table?
You may want to rethink your process before you use READ UNCOMMITTED. There are many good reasons for isolated transactions. If you use READ UNCOMMITTED you may still get duplicates because there is a chance both of the inserts will check for updates at the same time and both not finding them creating duplicates. Try breaking it up into smaller batches or issue periodic COMMITS
EDIT
You can wrap the MainTable update in a transaction that will free up that table quicker but you still may get conflicts with the other tables.
ie
BEGIN TRANSACTION
SELECT #ProcessedBit = ProcessedBit FROM MainTable WHERE ID = XXX
IF #ProcessedBit = False
UPDATE MainTable SET ProcessedBit = True WHERE ID = XXX
COMMIT TRANSACTION
IF #ProcessedBit = False
BEGIN
BEGIN TRANSACTION
-- start long running process
...
COMMIT TRANSACTION
END
EDIT to enable error recovery
BEGIN TRANSACTION
SELECT #ProcessedStatus = ProcessedStatus FROM MainTable WHERE ID = XXX
IF #ProcessedStatus = 'Not Processed'
UPDATE MainTable SET ProcessedBit = 'Processing' WHERE ID = XXX
COMMIT TRANSACTION
IF #ProcessedStatus = 'Not Processed'
BEGIN
BEGIN TRANSACTION
-- start long running process
...
IF No Errors
BEGIN
UPDATE MainTable SET ProcessedStatus = 'Processed' WHERE ID = XXX
COMMIT TRANSACTION
ELSE
ROLLBACK TRANSACTION
END
The only isolation level that allows one transaction to read changes executed by another transaction in progress (before it commits) is:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED