views:

214

answers:

11

Why didn't the designers of SQL require a keyword (e.g. "All") for any Update or Delete statements that don't have a Where clause? Was it just an oversight on their part? They would have saved so much grief (not to mention jobs!) if they had done that!

+1  A: 

For the same reason you can have a malloc without matching free in C : it's your responsibility.

turbovince
... And for that matter why have compiler complain when you make errors?! It's your responsibility to have perfect bug-free code!
MGOwen
A: 

But really the issue is how safe is your 'Live' data. Running untested scripts on a 'Live' database is asking for trouble.

Brody
+1  A: 

I don't know why either.

I bloody wish they did. The few times I want an update all or delete all I can be bothered to write WHERE 1 = 1.

Of course that wouldn't have saved Manoj who wrote

DELETE FROM T2
  FROM Tbl T1, Tbl T2
 WHERE T1.TopLevelId = 'value'
Joshua
where 1=1? That would truly get up my nose after a while.
paxdiablo
+4  A: 

There are so many other really easy ways to corrupt your SQL data that trying to catch any one of them is really just a waste of time. An UPDATE without a WHERE is just as bad (arguably worse). Leaving off a clause or two in a SELECT joining multiple tables could cause it to print to your console, instead of one row, a trillion.

Work on replicated slaves when possible. When you can't, make sure backups are available that won't be instantly corrupted by updates. And when typing UPDATE or DELETE queries, type slowly and carefully and always stare at it for a few seconds before you type the closing semicolon.

Jamie McCarthy
+1  A: 

I have never seen a case in which all records needed to be deleted, and precious few where all should be updated. I've always considered it a design flaw.

recursive
What're you talking about? (1) Clearing out a database is common during development and testing. (2) Updating is also common if you add a column to a table and you want to set all exiting rows to use a specific (or variable) value.
paxdiablo
(1) That's what truncate is for. (2) It's true that this does occur, but is by far the minority case. I'd rather add a WHERE 1=1 clause to these than risk an unintentional disaster.
recursive
1. truncate is non logged. what if my dependent table had all the records for a particular id for master and I wanted to roll back after delete ?
Learning
Then I'd suggest that you shouldn't have deleted them in the first place. (perhaps a DELETE WHERE) would have accomplished what you were looking for. Otherwise, there is always DELETE WHERE 1=1.
recursive
+1  A: 

I think you'll find that they assumed you would know what you were doing, and display some modicum of intelligence :-).

I know, let's play "Reductio Ad Absurdum":

  • You should not be able to delete[] in C++ without an ALL keyword. What if you just wanted to delete one element of the array?
  • All those iterators that people seem to love are dangerous without forcing their users to specify ALL. What if they just wanted a subset?
  • Mon Dieu! What if people were to leave a WHERE clause off their SELECT? The potential for harm is truly stupendous, it could take hours to retrieve all that data, tying up a valuable DBMS connection for the duration.

Please don't be offended, I'd prefer you to take this in the spirit it's intended (light humor). I think, as professionals, we should know what we're doing. Granted, I've made some beautiful mistakes such as appending to the passwd file with:

echo "....." >/etc/passwd

instead of using ">>" which is why I test all my potentially destructive stuff pretty thoroughly nowadays.

paxdiablo
You can use "set noclobber" to prevent your password file overwrite example.
JoelFan
I was young and stupid. Now I'm older and, one hopes, a little smarter :-)
paxdiablo
Consider that most enterprise-level databases log all SQL actions, so you can restore if you accidentally delete everything. If you want to delete with no undo, you use TRUNCATE TABLE instead. You could argue, then, that it's not the place of SQL to protect you from excessive deletes; maybe it's the place of the database or the database management tool instead. But the notion that there should be no protection from deletes because only someone without a "modicum of intelligence" would screw up is condescending and unnecessary...and quite mistaken to boot.
Kyralessa
+2  A: 

Where is it written that you need to write an SQL statement that is executable without a WHERE clause? As I type them in, I type them out-of-order so that it's not a legal SQL statement until I'm done. In other words, I type out the WHERE clause, then go back in and fill in the DELETE or UPDATE portion.

And whenever I'm doing something on a non-development environment, I perform a SELECT first to ensure that I get the proper rows with my WHERE condition, and then change it to a DELETE/UPDATE.

scwagner
+1 to selecting first and UPDATEing / DELETEing afterwards.
Daniel Magliola
I always type **elete** and add the **d** after I double check it.
MGOwen
A: 

As Murphy opined : If a thing can go wrong it will. "All" would be just another case.

Learning
+7  A: 

After making this mistake I've religiously gotten into the habit of typing


BEGIN TRANSACTION;

-- Select Blah

-- Some Sql here that changes Blah

-- Select Blah

ROLLBACK TRANSACTION;

then running it, making sure the rows affected count looks sane, staring at the Sql some more, then replacing ROLLBACK with COMMIT and running it for good.

It only takes 15 extra seconds and saves me some heartburn, especially on complex UPDATE...FROM type queries.

And indeed, I agree, there should have been an ALL keyword or some such to prevent flub ups like this. Or, a built in option in your Sql query environment that acts like the cash registers when I'd have a finger spasm and double-punch the screens at Taco Bell: "Did you REALLY mean 99 tacos?"

Nicholas Piasecki
This is my preferred protection too.
pjp
Just watchout if you're deleting thousands of records as the tranaction log can start to fill up. In this case it's a good idea to use set rowcount to something reasonable and repeatedly execute the transactional statement.
pjp
I do something similar. This also makes it easy to run over and over as you tune the SQL. I usually type out both ROLLBACK TRANSACTION and COMMIT TRANSACTION, and comment out the latter; that makes it even easier to see which one is in force. When I'm done working on the SQL, I switch the commenting to the other and run.
Kyralessa
+1  A: 

Loads of IT stuff was (is) written with the user last, and ease of development first. Sql is a great example, it works but many (trivially) easy things to do are hard. Yet things that are hard - like deleteing all your data is easy. I see it as a design flaw.

MrTelly
A: 

I believe this is due to the set-theory inspired nature of the SQL data manipulation language.

Use transactions :)

jeje