开发者

Updating rows using "in" operator in "where" clause

I stumbled upon SQL behavior I don't understand. I needed to update several rows in a table at once; started with just finding them:

SELECT * FROM some_table WHERE field1 IN (SELECT ...)

This returned a selection of about 60 rows. Now I was pretty confident I got the subquery right, so I modified the first part only:

UPDATE some_table SET field2 = some_value WHERE field1 IN (SELECT ...)

In other words, this was exactly as the first query after the WHERE. However, it resulted in 0 rows updated, whereas I would expect those 60. Note that the statement above would change field2, i.e. I verified that some_value was not present in the selected rows.

The subquery was a modestly complicated SQL piece with 2 (different) tables, 1 view, joins and its own WHERE clause. In case this matters, it happened with Oracle Database 10g.

开发者_StackOverflow

So, the question is, why UPDATE didn't touch the rows returned by SELECT?


Finally nailed it down. Turned out that the view used in subquery selection indirectly (through another view) called a stored procedure/function. The procedure then accessed the table that was being modified in UPDATE. As a result, Oracle threw exception to the tune of "table some_table is being modified and function may not see the result" (don't remember the exact text). But the function used when other then return null in the end, so the error was effectively hidden and the subquery didn't return anything at all — and in turn UPDATE had no effect.

Moral: never use overbroad exception catchers. I follow this rule in other languages, but apparently not in PL/SQL :-/


If "some-table" is actually a view, you may have hit an issue where the system is not able to work out how to update the tables that underlie the view.


I had a problem once where I had mistyped a column name, but there was a column with the same name in the other select, so my inner query "worked" by joining against the outer table.
If you just run the inner query by itself (no outer select or update) does it work?


Could be Row-Level Security (also known as Virtual private Database) where you've been given permission to read rows of a table, but not to update them.

Any database links involved ?


Is it that your field1 is not the first column returned from your subquery? I suspect that your IN would only compare the value to the results' first column.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜