SQL Update несколько полей FROM с помощью инструкции SELECT

Это работает, но я хотел бы удалить избыточность. Есть ли способ объединить обновление с одним оператором select, поэтому мне не нужно использовать vars?

    DECLARE
        @OrgAddress1 varchar,
        @OrgAddress2 varchar,
        @OrgCity varchar,
        @OrgState varchar,
        @OrgZip varchar,
        @DestAddress1 varchar,
        @DestAddress2 varchar,
        @DestCity varchar,
        @DestState varchar,
        @DestZip varchar

    SELECT 
        @OrgAddress1    =   OrgAddress,
        @OrgAddress2    =   OrgAddress2,
        @OrgCity        =   OrgCity,
        @OrgState       =   OrgState,
        @OrgZip         =   OrgZip,
        @DestAddress1   =   DestAddress,
        @DestAddress2   =   DestAddress2,
        @DestCity       =   DestCity,
        @DestState      =   DestState,
        @DestZip        =   DestZip
    FROM 
        ProfilerTest.dbo.BookingDetails 
    WHERE 
        [email protected]

    UPDATE SHIPMENT
    SET
        OrgAddress1     =   @OrgAddress1,
        OrgAddress2     =   @OrgAddress2,
        OrgCity         =   @OrgCity,
        OrgState        =   @OrgState,
        OrgZip          =   @OrgZip,
        DestAddress1    =   @DestAddress1,
        DestAddress2    =   @DestAddress2,
        DestCity        =   @DestCity,
        DestState       =   @DestState,
        DestZip         =   @DestZip
    WHERE 
        [email protected] MyID2

Ответы на вопрос(6)

UPDATE s
SET    OrgAddress1 = bd.OrgAddress1,    OrgAddress2 = bd.OrgAddress2,    
     ...    DestZip = bd.DestZip
--select s.OrgAddress1, bd.OrgAddress1, s.OrgAddress2, bd.OrgAddress2, etc 
FROM    Shipment s
JOIN ProfilerTest.dbo.BookingDetails bd on  bd.MyID =s.MyID2
WHERE    bd.MyID = @MyId 

Таким образом, объединение является явным, поскольку неявные объединения являются ИМХО плохой вещью. Вы можете запустить закомментированный выбор (обычно я указываю поля, в которых я обновляю старые и новые значения рядом друг с другом), чтобы убедиться, что то, что я собираюсь обновить, именно то, что я хотел обновить.

 12 авг. 2009 г., 22:43
Даже не заметил, что, возможно, перекрестное соединение - лучшее решение. Только ОП знает наверняка.
 12 авг. 2009 г., 22:07
Я не уверен, учитывая, что в исходном примере существует отношение один к одному (или много) между BookingDetails и Отправкой для bd.MyID к s.MyID2. В приведенном примере (допустим, я предполагаю) два разных параметра для идентификаторов, поэтому я предполагаю, что они могут быть разными. Я согласен с тем, что если существует явное соединение, его следует использовать!

что-то вроде:

обновить комплект поставки .... от отгрузка внутреннее соединение ProfilerTest.dbo.BookingDetails на ...

Решение Вопроса

о памяти):

UPDATE SHIPMENT
SET
  OrgAddress1     = BD.OrgAddress1,
  OrgAddress2     = BD.OrgAddress2,
  OrgCity         = BD.OrgCity,
  OrgState        = BD.OrgState,
  OrgZip          = BD.OrgZip,
  DestAddress1    = BD.DestAddress1,
  DestAddress2    = BD.DestAddress2,
  DestCity        = BD.DestCity,
  DestState       = BD.DestState,
  DestZip         = BD.DestZip
FROM
   BookingDetails BD
WHERE 
   SHIPMENT.MyID2 = @MyID2
   AND
   BD.MyID = @MyID

Это помогает?

 05 нояб. 2010 г., 17:24
@Jody: вопрос касался SQL Server, а не Oracle, поэтому я дал решение, которое работает в SQL Server.
 Christopher Kelly12 авг. 2009 г., 22:26
работает как шарм, я знал, что должен быть способ сделать обновление, основанное на утверждении select, но как меня ускользнуло.
 05 нояб. 2010 г., 16:25
К вашему сведению - это не работает в оракуле. Вместо этого вы можете использовать & lt; code & gt; обновить (выберите table1.field1 как a1, table2.field2 как b1 из table1, table2, где field1 = field2) установите a1 = b1 примечание: я думаю, что псевдонимы необходимы, если ваши поля имеют одно и то же имя по какой-то причине.
 08 нояб. 2018 г., 12:40
@IbrahimOudah Ответ сказал мне, что делать, и комментарий Джоди, почему я раньше не видел этот синтаксис
 20 дек. 2014 г., 04:53
@marc_s НО ХОРОШО ОТ ДЖОДДЫ, ЧТО ОН ОБЕСПЕЧИВАЕТ ДРУГИХ О ORACLE.

UPDATE s SET
  s.Field1 = q.Field1,
  s.Field2 = q.Field2,
  (list of fields...)
FROM (
  SELECT Field1, Field2, (list of fields...)
  FROM ProfilerTest.dbo.BookingDetails 
  WHERE [email protected]
) q
WHERE [email protected] MyID2

когда я добавил порядковый номер (чтобы элементы, сгруппированные по родительскому идентификатору, имели последовательность, по которой я могу упорядочить (и, вероятно, пользователь может изменить порядковый номер, чтобы изменить порядок).

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

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

Этот SELECT возвращает вам новый порядковый номер:

select PatientID,
       PatientInsuranceID, 
       Sequence, 
       Row_Number() over(partition by PatientID order by PatientInsuranceID) as RowNum
from PatientInsurance
order by PatientID, PatientInsuranceID

Эта команда обновления будет простой, но не допускается:

update PatientInsurance
set Sequence = Row_Number() over(partition by PatientID order by PatientInsuranceID)

Решение, которое работало (я только что сделал это), и похоже на решение eKek0:

UPDATE PatientInsurance
SET  PatientInsurance.Sequence = q.RowNum
FROM (select PatientInsuranceID, 
             Row_Number() over(partition by PatientID order by PatientInsuranceID) as RowNum
      from PatientInsurance
     ) as q 
WHERE PatientInsurance.PatientInsuranceID=q.PatientInsuranceID 

это позволяет мне выбрать идентификатор, который мне нужен, и значение, которое нужно установить для этого идентификатора. Другие решения были бы хорошими, если бы я не использовал Row_Number (), который не будет работать вне SELECT.

Учитывая, что это однократная операция, ее кодирование все еще простое, и скорость выполнения достаточно высока для 4000+ строк.

UPDATE s
SET
    OrgAddress1 = bd.OrgAddress1,
    OrgAddress2 = bd.OrgAddress2,
    ...
    DestZip = bd.DestZip
FROM
    Shipment s, ProfilerTest.dbo.BookingDetails bd
WHERE
    bd.MyID = @MyId AND s.MyID2 = @MyID2

Оператор FROM можно сделать более оптимистичным (используя более конкретные объединения), но вышеприведенное должно помочь. Кроме того, приятным дополнительным преимуществом является то, что вы можете написать его таким образом, чтобы увидеть предварительный просмотр изменения ОБНОВЛЕНИЯUPDATE s SET читатьSELECT! Затем вы увидите эти данные такими, какими они будут, если бы обновление имело место.

 12 авг. 2009 г., 21:26
Что ж, возник вопрос о том, зачем указывать Отгрузку в предложении FROM, а не после обновления. Ответ marc_s выше, и это фактически тот же план выполнения в MSSQL
 12 авг. 2009 г., 21:22
Такая же разница. Это чище для меня. Я не выбираю дважды. Я получаю только результаты от s, как от предложения FROM.

Ваш ответ на вопрос