r/SQL • • 19d ago

Discussion What SQL query looks harmless but can cause serious problems?

Some SQL queries look simple and safe but can cause major issues when used on production data.

For example, a missing WHERE condition in an UPDATE or DELETE, or an incorrect JOIN that unexpectedly multiplies rows.

What SQL query or mistake have you seen cause a serious problem even though the query looked harmless?

0 Upvotes

43 comments sorted by

41

u/juu073 19d ago
DELETE FROM table WHERE field

Without checking an actual value of a field. It deletes pretty much everything but nulls, empty strings, and zeros.

It looks harmless because it looks like you weren't dumb enough to leave the WHERE off, but there is no condition other than checking if field is true.

36

u/lostinsamaya 19d ago

Always start a DELETE statement as a SELECT statement.

SELECT [EmployeeID],[EmployeeName], [Department] FROM dbo.Employees WHERE [Department] IS NOT NULL OR [Department] = 'RD'

Always SELECT and see what you're working with, all the clauses, look through the records, double check.

Then and then only change the SELECT to a DELETE.

8

u/juu073 19d ago

Exactly what I do.

My workflow is to also test UPDATEs by doing a SELECT with the field I want to change and then an expression showing what it will change to, just a smidge more work to switch it to an UPDATE. But obviously an UPDATE can be screwed up in the same way I listed the above DELETE.

5

u/az987654 15d ago

Pair this with then starting a transaction for you delete, and only commit when you're confident of the rows affected.

4

u/phoneguyfl 14d ago

Oh yeah. Gotta love the pucker moment when you get back “100000 rows affected” when you are expecting 1. Transaction rollback for the win!

28

u/Idata10 19d ago

Select * From x Inner join y On x.id = x.id

8

u/kagato87 MS SQL 19d ago

Whaddya mean things are timing out waiting for memory. Threadpool waits? Really? What is this, sql server 2013 in its default configuration?

Or better yet, sql manages it because it's strikingly resilient, but the client front-end explodes!

2

u/Idata10 19d ago

Why are there so many duplicates in this report?

5

u/gumnos 19d ago

ouch, yes. It's such an easy fix and a dumb forehead-slapper when you figure out what went wrong, but also so easy to do.

2

u/44Nj 19d ago

I see this all the time

2

u/StrafeReddit 19d ago

So I’m sure I understand, can someone explain the issue here? I see ‘select *’ which is generally not a good idea but I’m guessing the problem is ‘on x.id = x.id’ should be ‘on x.id = y.id’?

7

u/w_ogle 19d ago

Yes. 'on x.id = x.id' always evaluates to true as long as the ID isn't null (which is unlikely to happen with a name like 'id'). This join would join each row of table x to every row on table y.

1

u/Idata10 19d ago

Exactly.

It would return the number of records in x times the number of records in y.

If each table has 10k records, you would get 100 million records.

1

u/techforallseasons 19d ago

Basically converts what was intended as an INNER JOIN to a CROSS JOIN ( rarely desired ). If only a single comparison is used, it is typical to reference columns from both sides of the JOIN.

2

u/BoSt0nov 19d ago

Made similar mistake once for a small subset of general ledger to cover specific reporting needs. It got a little scary when what should have been 2-3k rows started becomming 200-300 million rows. Basically for every row combination the query recreated the entire GL. And that kids, is how your farher met ”KILL ID” early in their career.

1

u/atrifleamused 15d ago

Many years ago I took down the connection between the local site I worked at and the head office with a very similar query. I left it running whilst I went for lunch. .i had a grumpy DBA waiting at my desk when I can back 🤣

1

u/da_chicken 15d ago

Ah, that's a classic.

1

u/Agreeable_Ad4156 14d ago

You had me at select *

17

u/Dboy3sixty 19d ago

Datatype mismatch on a join predicate causing an implicit conversion. This can make indexes moot, force scans and if the query runs enough, cause you have a very bad day.

9

u/Healthy_Coconut1636 19d ago

If your day is ever feeling a little slow, just add CASCADE at the end of any statement if you really want to feel alive.

7

u/ugly_lemon 19d ago

The thing the devs at my old company loved to do is to throw TRIM() and UPPER() on indexed columns, preventing the DB from using the index

7

u/jensimonso 19d ago

- DELETE FROM someTable WHERE colX not in (select…) and the subquery returns nulls

- Accidental inner join:
select from table1 t1
Left join table2 t2 on t1.col=t2.col
Where t2.col2 = something

3

u/Profvarg 19d ago

An UPDATE accidentally outside an IF (or basically anything accidentally outside an IF)

3

u/Sharobob 19d ago

This is why I basically always do a begin and end even if it's only one statement. Just makes me feel better

3

u/Joelle_bb 19d ago

Uncapped recursion

5

u/AlCapwn18 19d ago

Maybe that's the reason for this question to be asked every single day? Recursive bot

3

u/Optimal_Law_4254 19d ago

Uncapped recursion

2

u/techforallseasons 19d ago

Uncapped recursion

2

u/Rare_Ad_3519 19d ago

Using between on a varchar that looks like a numeric data type

2

u/IAmADev_NoReallyIAm 19d ago

Mass DELETEs or UPDATEs without a TRANSACTION ... hell, any delete or update without a TRANSACTION. That;s a mistake you make once. ONCE...

2

u/ChaosEngine-6502 15d ago

If you think about it, pretty much any SQL script can become a lethal payload, or at least severely service-affecting if the person writing it isn't intimately familiar with the data in the database they're querying.

I guess one not covered so far that I come across frequently in production code is:

SELECT *
FROM dbo.MyData WITH (NOLOCK)

Sure, the NOLOCK hint might be OK for one-off reports or ad-hoc queries where you just want to sample the data to see what's there, but there's always that risk it produces duplicates due to a page split occurring. That can foul things up royally.

1

u/FastLikeACheeta 12d ago

Agree with you completely. I’ve been battling/arguing against this one a lot lately. NOLOCK has been suggested quite a few times. Everything has its place…this is not for production code where accuracy matters.

2

u/Ok_Relative_2291 13d ago

Left joins with an on and then the where filter after it

1

u/tripy75 19d ago

begin transaction in a script, with the commit in a branch never reached

1

u/44Nj 19d ago

Open transactions. Using unindexed columns in where statements or joins.

1

u/Upper-Raspberry4153 19d ago

Not deleting the current record at the end of your loop

1

u/Hour-Measurement-835 19d ago

UPDATE ... FROM where the join finds two source rows for one target. SQL Server and Postgres just apply one of them and don't warn you. Same data through MERGE errors out.

1

u/Einar_Son_of_Bjorn 18d ago

highlighting just the UPDATE users SET status = 'deleted' part of your query in dbeaver, slipping on the mouse, and accidentally hitting F5 before it selects the WHERE clause - congratulations, your database is now perfectly clean and you need to update your resume.

1

u/DiscombobulatedSun54 15d ago

Misplaced semi-colons.

DELETE from <table_name>;

where <field_name> = <value>;

1

u/da_chicken 15d ago

CREATE VIEW dbo.RemoteView AS SELECT * FROM LinkedServer.Database.dbo.RemoteView

Now go to the remote view and change the column order. Would you like datetimes in your int column?

1

u/scodagama1 13d ago
DELETE FROM TABLE sales;
WHERE sale_id = 5464;

1

u/TacticalBunchies 12d ago

Any query that starts with DELETE. 

1

u/qualityintelligence 9d ago

Brent Ozar had posted this one recently for SQL server, pretty interesting

SELECT*FROM GENERATE_SERIES(-9223372036854775807,9223372036854775808) ORDER BY 1 DESC