Как обновить две таблицы в одном операторе в SQL Server 2005? - PullRequest
171 голосов
/ 11 января 2010

Я хочу обновить две таблицы за один раз. Как мне это сделать в SQL Server 2005?

UPDATE 
  Table1, 
  Table2
SET 
  Table1.LastName='DR. XXXXXX', 
  Table2.WAprrs='start,stop'
FROM 
  Table1 T1, 
  Table2 T2
WHERE 
  T1.id = T2.id
AND 
  T1.id = '010008'

Ответы [ 8 ]

178 голосов
/ 11 января 2010

Вы не можете обновить несколько таблиц в одном операторе, однако вы можете использовать транзакцию, чтобы убедиться, что два оператора UPDATE обрабатываются атомарно. Вы также можете дозировать их, чтобы избежать поездки в оба конца.

BEGIN TRANSACTION;

UPDATE Table1
  SET Table1.LastName = 'DR. XXXXXX' 
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
and T1.id = '011008';

UPDATE Table2
SET Table2.WAprrs = 'start,stop'
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
and T1.id = '011008';

COMMIT;
76 голосов
/ 12 января 2010

Вы не можете обновить две таблицы одновременно, но вы можете связать обновление со вставкой, используя OUTPUT INTO, и вы можете использовать этот вывод как объединение для второго обновления:

DECLARE @ids TABLE (id int);
BEGIN TRANSACTION

UPDATE Table1 
SET Table1.LastName = 'DR. XXXXXX'  
OUTPUT INSERTED.id INTO @ids
WHERE T1.field = '010008';

UPDATE Table2 
SET Table2.WAprrs = 'start,stop' 
FROM Table2 
JOIN @ids i on i.id = Table2.id;

COMMIT;

Я изменил ваш пример, где условие WHERE является некоторым другим полем, чем id, если id, то вам не нужен этот причудливый OUTPUT, вы можете просто ОБНОВИТЬ вторую таблицу для того же id = '010008'.

18 голосов
/ 11 января 2010

Извините, афаик, вы не можете этого сделать. Чтобы обновить атрибуты в двух разных таблицах, вам необходимо выполнить два отдельных оператора. Но они могут быть в пакете (набор SQL, отправленных на сервер за один прием)

14 голосов
/ 16 марта 2011

Короткий ответ на этот вопрос - нет. Хотя вы можете ввести несколько таблиц в предложении from оператора обновления, вы можете указать только одну таблицу после ключевого слова update. Даже если вы напишете «обновляемое» представление (которое является просто представлением, которое следует определенным ограничениям), обновления, подобные этому, не будут выполнены. Вот соответствующие клипы из документации MSDN (выделено мое).

ОБНОВЛЕНИЕ (Transact-SQL)

Представление, на которое ссылается table_or_view_name, должно быть обновляемым и ссылаться на ровно на одну базовую таблицу в предложении FROM представления. Для получения дополнительной информации об обновляемых представлениях см. CREATE VIEW (Transact-SQL).

CREATE VIEW (Transact-SQL)

Вы можете изменить данные базовой базовой таблицы через представление, если выполняются следующие условия:

  • Любые модификации, включая операторы UPDATE, INSERT и DELETE, должны ссылаться на столбцы из только одной базовой таблицы .
  • Столбцы, изменяемые в представлении, должны напрямую ссылаться на базовые данные в столбцах таблицы. Столбцы не могут быть получены любым другим способом, например, с помощью следующего:
    • Агрегирующая функция: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR и VARP.
    • Вычисление. Столбец не может быть вычислен из выражения, которое использует другие столбцы. Столбцы, сформированные с помощью операторов множеств UNION, UNION ALL, CROSSJOIN, EXCEPT и INTERSECT, представляют собой вычисление и также не могут быть обновлены.
  • На изменяемые столбцы не распространяются предложения GROUP BY, HAVING или DISTINCT.
  • TOP не используется нигде в select_statement представления вместе с предложением WITH CHECK OPTION.

Честно говоря, вы должны рассмотреть возможность использования двух разных операторов SQL в транзакции, как в примере с Л.Бушкиным.

ОБНОВЛЕНИЕ: Мое первоначальное утверждение, что вы можете обновить несколько таблиц в обновляемом представлении, было неверным. На SQL Server 2005 и 2012 он выдаст следующую ошибку. Я исправил свой ответ, чтобы отразить это.

Msg 4405, Level 16, State 1, Line 1

View or function 'updatable_view' is not updatable because the modification affects multiple base tables.

7 голосов
/ 11 января 2010

Вы должны поместить два оператора обновления в транзакцию

6 голосов
/ 22 мая 2014

Это работает для MySQL и на самом деле просто неявная транзакция, но она должна выглядеть примерно так:

UPDATE Table1 t1, Table2 t2 SET 
t2.field = t2.field+2,
t1.field = t1.field+2

WHERE t1.id = t2.foreign_id and t2.id = '123414'

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

1 голос
/ 10 сентября 2016

Вы можете написать update оператор для одна таблица , а затем триггер on первая таблица update, которая обновит вторую таблицу

0 голосов
/ 02 июня 2018

Это так же просто, как этот запрос, показанный ниже.

UPDATE 
  Table1 T1 join Table2 T2 on T1.id = T2.id
SET 
  T1.LastName='DR. XXXXXX', 
  T2.WAprrs='start,stop'
WHERE 
  T1.id = '010008'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...