LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-25-2020, 06:07 PM   #1
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
SQL inner query conundrum


I recently suffered through a minor database disaster. The query I meant to run was something like this
Code:
delete from table_a where x_id in (select x_id from table_b where field_a = 2345)
What I in fact ran was:
Code:
delete from table_a where x_id in (select x_id from table_c where field_a = 2345)
Now, table_c didn't have a field x_id but instead of exiting with an error all records were deleted from table_c. We were able to recover using backups and transaction logs.

This was run on SQL Server. I verified the behavior substituting 'select count(*)' for delete.

I was shocked by this since my expectation is that the query would fail however I found this on a Microsoft page discussing subqueries:
Quote:
If a column is referenced in a subquery that does not exist in the table referenced by the subquery's FROM clause, but exists in a table referenced by the outer query's FROM clause, the query executes without error. SQL Server implicitly qualifies the column in the subquery with the table name in the outer query.
In the query in question table_a did not have a column named field_a so SQL Server must not only have satisfied the requirement for x_id in the subquery but also ignored the where clause giving
Code:
delete from table_a where x_id in (select x_id from table_a)
If this is what it does I have to wonder is this an expected SQL Server behavior? A SQL behavior? A bug perhaps?

To me it makes no sense.

Last edited by SoftSprocket; 12-25-2020 at 06:09 PM.
 
Old 12-26-2020, 05:30 PM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206
As no one else has stepped up I'll offer a few comments.

Code:
delete from table_a where x_id in (select x_id from table_b where field_a = 2345)
First comment: I avoid SQL Server same as I avoid anything from the source, so cannot offer help specific to the platform. An initial quick test indicated to me that MySQL behaved differently, but after paying better attention I am suitably horrified to find that is not the case when table_a has a column of same name - yikes!

I suppose the relevant logic is that described by MySQL as correlated subqueries, which permits references to tables in the outer query from within the subquery. That combined with implicit qualification of field names results in this behavior.

BUT:

Quote:
Originally Posted by SoftSprocket View Post
In the query in question table_a did not have a column named field_a so SQL Server must not only have satisfied the requirement for x_id in the subquery but also ignored the where clause
MySQL definitely fails with an Unknown column in where clause in this case. I am surprised at that behavior even for a micros-chism! That fails the implicit qualification case described so that is a pretty serious error.

Second comment: My own habit is to explicitly qualify table.column in all but the simplest queries, and to avoid subqueries wherever possible as it is almost always possible|better to do it with a join. For the example you posted my own approach would have been something like...

Code:
DELETE table_a FROM table_b JOIN table_a USING(x_id) where table_b.field_a=2345
That said, I have no idea whether that platform supports multi-table delete, but if so this would have kept you out of that particular spot of trouble.

Last edited by astrogeek; 12-26-2020 at 06:33 PM. Reason: typos, comments, gotcha
 
Old 12-26-2020, 07:21 PM   #3
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by astrogeek View Post

MySQL definitely fails with an Unknown column in where clause in this case. I am surprised at that behavior even for a micros-chism! That fails the implicit qualification case described so that is a pretty serious error.
I think the issue there was that the column in the where clause was valid in the second table as well. I suppose the fact that it had no relevance to the query, since the only column in the subquery was being satisfied by the outer query, isn't enough to invalidate the whole thing.

Quote:
Originally Posted by astrogeek View Post
Second comment: My own habit is to explicitly qualify table.column in all but the simplest queries, and to avoid subqueries wherever possible as it is almost always possible|better to do it with a join. For the example you posted my own approach would have been something like...

Code:
DELETE table_a FROM table_b JOIN table_a USING(x_id) where table_b.field_a=2345
That said, I have no idea whether that platform supports multi-table delete, but if so this would have kept you out of that particular spot of trouble.
It does and I have to often write that particular query and would have had to look up (well, I gues I should have). Using a join in the inner query also prevents the query from being satisfied by the outer query. Live and learn.
 
  


Reply

Tags
sql subquery



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Simulate SQL inner join in bash? taylorkh Linux - Software 8 01-24-2020 08:40 AM
Java: what's the difference between an inner class and a static inner class? irey Programming 6 01-28-2009 03:34 AM
getting rid of an extended partition preserving the inner ones discShredder Linux - Newbie 4 02-23-2004 11:00 AM
can't use protected inner class when inheriting the outer Dominik Programming 6 02-02-2004 01:12 AM
Java - Interfaces, inner classes and callbacks for events gwp Programming 3 12-09-2003 04:25 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration