Обновление строк с помощью оператора "in" в предложении "where" - PullRequest
4 голосов
/ 19 апреля 2010

Я наткнулся на поведение SQL, я не понимаю. Мне нужно было обновить несколько строк в таблице одновременно; начал с того, что просто нашел их:

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

Это вернуло выбор около 60 строк. Теперь я был уверен, что правильно понял подзапрос, поэтому я изменил только первую часть :

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

Другими словами, это было точно так же, как первый запрос после WHERE. Однако это привело к обновлению 0 строк, тогда как я ожидал бы, что эти 60. Обратите внимание, что приведенный выше оператор изменит , изменит field2, то есть я убедился, что some_value не присутствовал в выбранных строках. *

Подзапрос представлял собой скромно сложную часть SQL с 2 (разными) таблицами, 1 представлением, объединениями и собственным предложением WHERE. В случае, если это имеет значение, это произошло с Oracle Database 10g.

Итак, вопрос в том, почему UPDATE не коснулся строк, возвращенных SELECT?

Ответы [ 5 ]

4 голосов
/ 21 апреля 2010

Наконец прибил его. Оказалось, что представление, используемое в выборе подзапроса косвенно (через другое представление), называется хранимой процедурой / функцией. Затем процедура получила доступ к таблице, которая была изменена в UPDATE. В результате Oracle сгенерировал исключение для мелодии «таблица some_table изменяется, и функция может не увидеть результат» (не помню точный текст). Но функция использовала when other then return null в конце, так что ошибка была эффективно скрыта, и подзапрос вообще ничего не возвращал - и, в свою очередь, UPDATE не дал эффекта.

Мораль: никогда не используйте перехватчиков исключений за рубежом. Я придерживаюсь этого правила в других языках, но, очевидно, не в PL / SQL: - /

1 голос
/ 20 апреля 2010

Однажды у меня возникла проблема, когда я неправильно набрал имя столбца, но в другом выделенном столбце был столбец с тем же именем, поэтому мой внутренний запрос «работал», соединяясь с внешней таблицей. Если вы просто запустите внутренний запрос (без внешнего выбора или обновления), он будет работать?

1 голос
/ 19 апреля 2010

Если «some-table» на самом деле является представлением, возможно, вы столкнулись с проблемой, когда система не может решить, как обновить таблицы, лежащие в основе представления.

0 голосов
/ 21 апреля 2010

Это то, что ваше field1 не первый столбец, возвращенный из вашего подзапроса? Я подозреваю, что ваш IN будет сравнивать только значение с первым столбцом результатов.

0 голосов
/ 20 апреля 2010

Может быть защита на уровне строк (также называемая виртуальной частной базой данных), когда вам дано разрешение читать строки таблицы, но не обновлять их.

Есть ли ссылки на базы данных?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...