Обновление пользовательских отношений: требуется ли первичный ключ? - PullRequest
0 голосов
/ 24 октября 2018
UPDATE (
    SELECT
        o.order_id,
        o.shipping_from
    FROM
        orders o,
        items i
    WHERE
        o.item_id = i.item_id
        AND o.shipping_from = 'foot'
        AND i.type = 'ent'
) t
SET
    t.shipping_from = 'car';

Внутренний запрос SELECT возвращает 2 строки из orders.Весь запрос работает хорошо, как исключение.o.order_id и i.item_id - это первичные ключи, o.item_id - внешний ключ, имена других столбцов не совпадают.

Когда я запускаю обновление таким способом, требуется ли включать первичныйключ в отношении я хочу обновить?Зачем?Если нет, то как СУБД узнает, что строка находится в другой таблице?Конечно, items не имеет поля shipping_from, поэтому не ясно, какую строку я выбираю, но что, если она имеет?

Некоторые примеры данных:

SELECT * FROM items WHERE type = 'ent';
   ITEM_ID ITEM_SERIAL_CODE     NAME                 BRAND                TYPE         DAILY_COST PURCHASE_DAT
---------- -------------------- -------------------- -------------------- ------------ ---------- ------------
      1007 DC00755250           Dragon costume       Branded              ent               19000 14-DEC.  -15
      1010 SS01003632           Serpentine streamer  Chinese              ent              132500 10-MÁRC. -03

SELECT * FROM orders WHERE shipping_from = 'foot';
  ORDER_ID    ITEM_ID   EVENT_ID LIABLE_PERSON   SHIPPING_T SHIPPING_F ORDER_COMMENT
---------- ---------- ---------- --------------- ---------- ---------- -----------------------------------
      3011       1006       2010 Géza Nagy       car        foot       It will be a great party.
      3018       1009       2011 Ferenc Nagy     boat       foot       Multiple celebs expected.
      3019       1010       2011 Ferenc Balázs   bus        foot       Changing weather, changing seasons.
      3020       1010       2012 Béci Patkó      boat       foot       Bring the stuff to the first floor.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Ответ на то, что я хотел знать, - нет.Первичный ключ не требуется в списке проекций, эффект UPDATE такой же, даже если o.order_id не выбран в подзапросе.Однако это не означает, что первичный ключ не используется, благодаря декларативной технике.Независимо от того, включен или исключен первичный ключ, создается тот же план выполнения для извлечения записей, которые будут обновлены:

SQL Developer's explain plan view

Проекция не сильно меняетсяздесь СУБД может идентифицировать каждую строку после операции хеширования, см. ответ Крокодилко.

Если вы ничего не выберете из таблицы (например, введите SELECT 1 FROM ...), вы не сможете выполнить обновлениекоманда, результат подзапроса - это просто обычный набор некоторых данных, который не может быть сопоставлен с таблицей.

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

0 голосов
/ 24 октября 2018

Требуется ли включить первичный ключ в отношение, которое я хочу обновить?Почему?

Да


Ответ приведен в документации: 24.1.5 DML-операторы и просмотры соединений

Обновление представления соединения

Обновляемое представление соединения (также называемое изменяемым представлением соединения) - это представление, которое содержит несколько таблиц в предложении FROM верхнего уровня инструкции SELECT,и не ограничивается предложением WITH READ ONLY.

Правила для обновляемых представлений объединения показаны в следующей таблице.Представления, которые соответствуют этим критериям, называются по своей сути обновляемыми.

  • Общее правило : любая операция INSERT, UPDATE или DELETE в представлении соединения может изменить только одну базовую базовую таблицу ввремя.
  • Правило ОБНОВЛЕНИЯ : Все обновляемые столбцы представления объединения должны отображаться в столбцы таблицы, сохраненной ключом.См. «Таблицы с сохранением ключей» для обсуждения таблиц с сохранением ключей.Если представление определено с помощью условия WITH CHECK OPTION, то все столбцы объединения и все столбцы повторяющихся таблиц не могут быть обновлены.

.......................

В контексте вышеприведенной документации подзапрос в выражении UPDATE (UPDATE ( subquery ) SET ...) рассматривается как представление , то естькак UPDATE the_view SET ... - потому что любое представление - это не что иное, как (под) запрос.

...