Могу ли я вставить / обновить в две таблицы одним запросом? - PullRequest
2 голосов
/ 17 августа 2011

Вот фрагмент SQL, который я использую для веб-приложения на основе Perl.У меня есть несколько запросов, и у каждого есть несколько образцов, и у каждого есть статус.Этот кусок кода предназначен для обновления таблицы для каждого accession_analysis, который разделяет все эти поля для каждого присоединения в запросе.

UPDATE accession_analysis
SET analysis_id = ? ,
    reference_id = ? ,
    status = ? , 
    extra_parameters = ?
WHERE analysis_id = ?
AND reference_id = ?
AND status = ?
AND extra_parameters = ?
and accession_id is (
    SELECT accesion_id
    FROM accessions
    where request_id = ?
    )

Я изменил таблицы так, чтобы была таблица состояния для accession_analysis, поэтому при обновлении я обновляю и accession_analysis, и accession_analysis_status, у которого есть status, status_text и id accession_analysis, который являетсяне нулевая переменная auto_increment.

У меня нет четкого представления о том, как изменить этот код, чтобы разрешить это.Мой первый проход захватил все образцы и прошел через них, затем отфильтровал все поля и обновил.Мне это не понравилось, потому что у меня было много соединений с короткими командами SQL, что, как я понял, было плохо, но я не могу не думать, что единственный способ действительно сделать это - вернуться к циклу в Perl, содержащему две более простыеОператоры SQL.

Есть ли способ сделать это в SQL, который, с моей относительной неопытностью в SQL, я просто не вижу?

Ответы [ 3 ]

2 голосов
/ 17 августа 2011

Ответ зависит от того, какую СУБД вы используете. Самый простой способ - создать триггер на одной таблице, который обеспечивает логику обновления другой таблицы. (Для любого новичка в БД - триггер - это процедурный код, прикрепленный к таблице на уровне СУБД (не приложения), который запускается в ответ на вставку, обновление или удаление в таблице.). Аналогичный, чуть менее желательный метод - поместить логику в хранимую процедуру и выполнить ее вместо оператора обновления, который вы сейчас используете.

Если используемая вами СУБД не поддерживает ни один из этих механизмов, то нет хорошего способа сделать то, что вам нужно, при этом гарантируя целостность транзакций. Однако если проблема, которую вы решаете, может допускать разницу во времени в обновлениях двух таблиц (т.е. данные в одной из таблиц используются только в заранее определенное время, например, отчеты или какой-то тип пакетной операции), вы можете записать в одну таблицу (в реальном времени) и создайте отдельный процесс, который запускается при необходимости (позже) для обновления второй таблицы с использованием данных из первой таблицы. Однако правильность разрешения обновления данных в разное время становится большим и неизменным предположением проекта.

2 голосов
/ 17 августа 2011

Если речь идет в основном о скорости соединения, то у вас есть возможность написать хранимую процедуру, которая прозрачно обрабатывает «двойное обновление или вставку».См. Руководство по хранимым процедурам:

http://dev.mysql.com/doc/refman/5.5/en/create-procedure.html

В противном случае вы, вероятно, не сможете сделать это в одном выражении, см. Синтаксис MySQL INSERT:

http://dev.mysql.com/doc/refman/5.5/en/insert.html

Синтаксис UPDATE позволяет обновлять несколько таблиц (но не в сочетании с INSERT):

http://dev.mysql.com/doc/refman/5.5/en/update.html

1 голос
/ 17 августа 2011

Каждая таблица нуждается в своем собственном INSERT / UPDATE в запросе.

Фактически, даже если вы создаете представление путем JOIN использования нескольких таблиц, когда вы INSERT входите в представление, вы можете INSERT только с полями, принадлежащими к одной из таблиц одновременно.

Изменения, сделанные оператором INSERT, не могут затрагивать более одной из базовых таблиц, указанных в предложении FROM представления. Например, INSERT в множественном представлении должен использовать column_list, который ссылается только на столбцы из одной базовой таблицы. Для получения дополнительной информации об обновляемых представлениях см. CREATE VIEW.

То же самое верно для UPDATE

Изменения, сделанные оператором UPDATE , не могут затрагивать более одной базовых таблиц, на которые есть ссылка в предложении FROM представления. Для получения дополнительной информации об обновляемых представлениях см. CREATE VIEW.

Однако вы можете иметь несколько INSERT с или UPDATE с на запрос или хранимую процедуру.

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