Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I preview a destructive SQL query?

Tags:

sql

sql-server

When writing destructive queries (e.g., DELETE or UPDATE) in SQL Server Management Studio I always find myself wishing I could preview the results of the query without actually running it. Access very conveniently allows you to do this, but I prefer to code my SQL by hand which, sadly, Access is very poor at.

So my question is twofold:

  1. Is there an add-on for SSMS, or a separate tool that is furnished with good SQL hand-coding facilities that can also preview the result of a destructive query, similar to Access?

  2. Are there any techniques or best practices for doing previews "by hand"; e.g., somehow using transactions?

It seems to me that doing this sort of thing is fundamentally important but yet I can't seem to find anything via Google (I'm probably just looking for the wrong thing - I am terribly ignorant on this matter). At present I'm taking a rather hairy belt and braces approach of commenting in and out select/delete/update lines and making sure I do backups. There's got to be a better way, surely?

Can anyone help?

like image 725
Charles Roper Avatar asked Jan 21 '09 12:01

Charles Roper


People also ask

How do I view the contents of a SQL database?

Right-click the Products table in SQL Server Object Explorer, and select View Data. The Data Editor launches. Notice the rows we added to the table in previous procedures. Right-click the Fruits table in SQL Server Object Explorer, and select View Data.

How can you check performance of a query?

Use the Query Store page in SQL Server Management Studio In Object Explorer, right-click a database, and then select Properties. Requires at least version 16 of Management Studio. In the Database Properties dialog box, select the Query Store page. In the Operation Mode (Requested) box, select Read Write.


5 Answers

I would use the OUTPUT clause present in SQL SERVER 2008 onwards...

OUTPUT Clause (Transact-SQL)

Something like...

BEGIN TRANSACTION

DELETE [table] OUTPUT deleted.* WHERE [woof] 

ROLLBACK TRANSACTION

INSERTs and UPDATEs can use the 'inserted' table too. The MSDN article covers it all.

EDIT:

This is just like other suggestions of SELECT then DELETE inside a transaction, except that it actually does both together. So you open a transaction, delete/insert/update with an OUTPUT clause, and the changes are made while ALSO outputting what was done. Then you can choose to rollback or commit.

like image 132
MatBailie Avatar answered Oct 04 '22 17:10

MatBailie


I live in fear of someone doing this to my databases so I always ask my Team to do something like the following:

BEGIN TRAN
 
DELETE FROM X
-- SELECT * FROM X
FROM Table A as X JOIN Table B ON Blah blah blah
WHERE blah blah blah
 
ROLLBACK TRAN
COMMIT TRAN

In this way, if you accidentally hit F5 (done it!) you'll do no changes. You can highlight the SELECT part through the end of the SQL statement to see what records will be changed (and how many). Then, highlight the BEGIN TRAN and entire Delete statement and run it. If you delete the same number of records you expected, highlight the COMMIT TRAN and run it. If anything looks wonky, highlight the ROLLBACK TRAN and run it.

I do this with any UPDATE or DELETE statement. It's saved me a couple times, but it ALWAYS provides peace of mind.

like image 43
Kevin Buchan Avatar answered Oct 04 '22 18:10

Kevin Buchan


When deleting:

BEGIN TRANSACTION

   DELETE FROM table1 
   OUTPUT deleted.*
   WHERE property1 = 99 

ROLLBACK TRANSACTION

When updating/inserting:

BEGIN TRANSACTION

   UPDATE table1
   SET table1.property1 = 99
   OUTPUT inserted.*

ROLLBACK TRANSACTION
like image 23
kravits88 Avatar answered Oct 04 '22 19:10

kravits88


When you are in the context of the transaction, you can rollback changes any time before the transaction is committed. (Either by calling commit tran explicitly or if a condition arises that will cause the server to implicitly commit the transaction)

create table x (id int, val varchar(10))

insert into x values (1,'xxx')
begin tran

delete from x
select * from x

rollback tran
select * from x
like image 21
cmsjr Avatar answered Oct 04 '22 18:10

cmsjr


When I want to see what will be deleted, I just change the "delete" statement to a "select *". I like this better than using a transaction because I don't have to worry about locking.

like image 42
BankZ Avatar answered Oct 04 '22 17:10

BankZ