Подтвердить что ты не робот

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
4b9b3361

Ответ 1

Что-то вроде этого должно работать (не могу проверить его прямо сейчас - из памяти):

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

Помогает ли это?

Ответ 2

Вы должны иметь возможность сделать что-то в соответствии с приведенными ниже

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 UPDATE s SET для чтения SELECT! Затем вы увидите, что данные будут отображаться, если обновление произошло.

Ответ 3

Вы можете использовать:

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

Ответ 4

вы можете использовать обновление из...

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

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

Ответ 5

Я бы написал это так

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 

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

Ответ 6

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

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

Проблема со всеми другими решениями заключается в том, что некоторые агрегированные функции не допускаются вне 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+ строк