BEGIN TRAN;
-- TODO: update statement
ROLLBACK;
Usually I'll run it with the ROLLBACK first, to confirm that it impacts the number of rows I'd expect, and only then change my ROLLBACK to a COMMIT.And yes, before that I had run an UPDATE without a WHERE in production..
Instead I do my dry run queries with a read only user and I select the affected data, often using CTEs (or temp tables where performance is an issue) to model any intermediate state. I don’t ever run any writes of this kind without review, backups, and automation.
Run code first, throw an error to force rollback the transaction...
However even with that, I agree with your second point. I always type
-- commit
in my SQL client and then highlight "commit" and execute only the highlighted text. That way I don't commit anything if I accidentally trigger the "execute all" action.It was a long time ago, but I think it was with SQLPlus on Oracle - and presumably staging or something non-prod since it's not a particularly vivid memory!
I went in there to adjust some data so that one of our dev users could re-publish some data which would then be synchronized to another database(update foo set published = false) and I couldn't understand that it wouldn't update in the UI.
I ended up telling him I'd have to get back to him, and the issue didn't dawn on me until the app logs started spitting out errors about not being able to retrieve a connection from the pool. YIL about pending transactions in DBeaver.
But our team learned the hard way that using transactions on the replica pg database actually locks it from getting updates globally during the duration of the transaction. And the whole idea of connecting to the replica was to not wreak havoc, oh well..
You shouldn't get access to prod if you didn't have experience with Oracle. The database is just too fragile to survive inexperienced people changing it.
Can't remember all the details. But something about adding a new nullable column with or without a default value of some kind. It had to lock the table, but multiple queries were already running. Those queries had some locks already, but then needed those rows the migration had already gotten hold of. Leading to this huge deadlock I had no idea how to solve.
Worst part is, it was one of the first times we tried deploying during working hours. At the time we normally only got to deploy 4 times a year, but we pushed for a more modern approach. Luckily the server guys were on our side, and a few years later that government agency is one of the best technical places I've seen after a complete revamp.
Well, this was back in the dark ages. Nowadays I'm sold on the notion that we shouldn't be running ad hoc stuff against the live prod database at all.
I'm sure there are exceptions, but I'll bet there are more temptations than solid reasons to do so!
Anyway, everybody should run their queries on a prod-like environment before running on prod, but on Oracle that's really not enough. Also the places that use expensive DBMSes tend not to have a lot of non-prod environments for people to test their scripts.
Nowadays Oracle supports you engineering your data so some of it is not on the bottleneck of anything and you can give some low amount of access to inexperienced people. But that's not the default situation.
Start with ROLLBACK at the bottom (With a BEGIN TRANSACTION up top if the DB/env warrants it)
Only when I know I'm happy, change the ROLLBACK to a COMMIT.
WHERE foo=bar LIMIT 1;
Then ctrl-a, and fill in the rest: —- UPDATE name=“new name” WHERE foo=bar LIMIT 1;
Then take a moment, read over what I typed, and hit ctrl-a again and remove the comment string.Ideally I’m doing this in an editor (not the db shell) as well, and when I’m done pass the saved file in on the commandline. I try to type as little as possible in the db shell unless I’m logged in as a read only user.
I also set my db shell to display the current username and database so it’s always right in front of me. And I never, ever use command history in shells to construct new commands. I swear that bit me more frequently than I got it right when I used to. It’s like a footgun with an extra footgun attachment.
This problem is fixed in query languages like EdgeQL.[0]
Not quite true, DISTINCT, ORDER BY and TOP/LIMIT happen afterwards.
Given the annoyance of this and its ability to really, really ruin your day, I don't know why someone hasn't updated their parser to allow 'update X where [cond] set [blah]' as an alternate phrasing.
Well, dangerous if you are using a simple terminal interface and not using a transaction when doing updates. The latter is generally a bad idea even if you aren't also doing the former.
I religiously write it out of order for this reason. The IDE complains for a bit, but it's better to deal with some squiggles for a few seconds until you've filled in the column assignments part.
At least for me, it’s safer to just… write the thing correctly in an environment incapable of running it.
That way ctrl+r won't bring back a destructive command.
Of course if the update is not only important but critical, manually starting a transaction before is the first step ;)
Linq is closest to the a more natural querying language we have come up with. Too bad it doesn't do update.
But that doesn't mean it's ideal. It just has a large most that people wasn't able to disrupt.
Check out linq both the sql-like form and the lambda form. It feels much better for what it does.
$ ls /
$ ls /tmp/junk; rm !$
It's taking "/" rather than "/tmp/junk"..EDIT: formatting
What you want is "ls /path; rm $_".
Even then, the above is fairly pointless. At the time you look at what you are deleting, it's gone.
1. ls /path
2. rm <esc><.>
(where "escape" "dot" brings up last argument) without the need to fiddle around with dollar signs underscores, exclamation marks, etc. to prevent further mistakes (e.g. "was it $! or !$ ?", shell expansion, etc)
Otherwise, simply having a mindset of, I'm doing dangerous things also goes a long way.
Never do things if you are in a panicked/frantic state.
Edit: I guess running galera is actually a blessing. I can't run any write/update methods on our qa/prod data...
Having run an `mkfs.ext3 /dev/sda` (note the missing partition number) by accident, I've learned to start potentially destructive commands by typing first whatever makes that command a comment (# in shell, -- in sql), then going back to the start of the line to remove the safety when I'm done.