tags:

views:

369

answers:

5

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?

+2  A: 

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
cmsjr
+14  A: 

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

OUTPUT Clause (Transact-SQL)

Something like...

BEGIN TRANSACTION

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

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, all while 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 outputing what was done. Then you can choose ot rollback or commit.

Dems
Superb, that's exactly what I've been after. Thank you. :)
Charles Roper
You're welcome :)
Dems
I prefer Kevin's solution because you can see the results without changing data. Select 100000 records is a whole bunch better for the database performance than delete 100000 records, output the results of deleted and then rollback.
HLGEM
But you're still open to mistakes. Like forgetting to highlight a where clause, etc. In this example you'd begin a transaction, make the change (which you fully intend to commit) OUPUT the changes and then leave the connection open with the transaction open. Once you have reviewed the output you can either COMMIT or ROLLBACK. This is much safer and much more reliable as it removes much more human error. It does mean the table is locked, so you need to be carefull still.
Dems
+9  A: 

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.

Kevin Buchan
I would put the DELETE and the SELECT the other way around for added safety.
Mr. Shiny and New
The reason I do it in the order listed is so that I can highlight the BEGIN TRAN and the DELETE statement together. If the DELETE were commented out, I'd have to do them separately, but that's just developer preference.Thanks for the comment.
Kevin Buchan
I like it. This is a good solution for those not on 2005+.
Charles Roper
This all works OK until someone forgets to COMMIT - and you end up blocking other users. I've seen that happen too many times, so be careful when using this strategy.
Scott Ivey
+1  A: 

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.

BankZ
I always try to put things in transactions any way. Just incase. Like highlighting everything except the where clause, hitting f5 and then staring blankly at the empty coffee mug...
Dems