Обновить таблицу из временной таблицы - PullRequest
2 голосов
/ 26 февраля 2009

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

У меня есть хранимая процедура для обновления основной таблицы, но она не работает, потому что она не будет обновлять пустые строки (если есть новая строка во временной таблице).

Это MSSQL Server 2005.

Где я тут ошибаюсь:

    -- Insert statements for procedure here
UPDATE [RX_Billing].[dbo].[FS_Drug]
SET [TRADENAME] = [RX_Billing].[dbo].[FS_Drug_TEMP].[TRADENAME]
  ,[CDM] = [RX_Billing].[dbo].[FS_Drug_TEMP].[CDM]
  ,[NDC] = [RX_Billing].[dbo].[FS_Drug_TEMP].[NDC]
  ,[IP_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[IP_COST]
  ,[OP_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[OP_COST]
  ,[HH_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[HH_COST]
  ,[VAR_COST] = [RX_Billing].[dbo].[FS_Drug_TEMP].[VAR_COST]
  ,[LSTUPDATE] = [RX_Billing].[dbo].[FS_Drug_TEMP].[LSTUPDATE]
FROM [RX_Billing].[dbo].[FS_Drug]
RIGHT OUTER JOIN [RX_Billing].[dbo].[FS_Drug_TEMP] ON 
          [RX_Billing].[dbo].[FS_Drug].[TRADENAME] = 
                   [RX_Billing].[dbo].[FS_Drug_TEMP].[TRADENAME]

EDIT:

Я пошел с кодом Рори. Спасибо, это прекрасно работает.

Примечание для Ориона Эдвардса: UPSERT / MERGE - это именно то, что я хотел, но он не поддерживается в SQL Server 2005. Очевидно, он был запланирован, но не был выпущен. Он доступен в Server 2008. (Из того, что мне сказали Интернет).

Ответы [ 3 ]

10 голосов
/ 26 февраля 2009

Стандартным способом является ОБНОВЛЕНИЕ, а затем ВСТАВКА:

-- UPDATE rows using an INNER JOIN with matching TRADENAME. No need to update TRADENAME column.
UPDATE drug
SET [CDM] = tmp.[CDM]
  , [NDC] = tmp.[NDC]
  , [IP_COST] = tmp.[IP_COST]
  , [OP_COST] = tmp.[OP_COST]
  , [HH_COST] = tmp.[HH_COST]
  , [VAR_COST] = tmp.[VAR_COST]
  , [LSTUPDATE] = tmp.[LSTUPDATE]
FROM [RX_Billing].[dbo].[FS_Drug] drug
INNER JOIN [RX_Billing].[dbo].[FS_Drug_TEMP] tmp  
    ON drug.[TRADENAME] = tmp.[TRADENAME]

-- Insert rows that don't have matching TRADENAME
INSERT INTO drug
SELECT 
    tmp.[TRADENAME]
  , tmp.[CDM]
  , tmp.[NDC]
  , tmp.[IP_COST]
  , tmp.[OP_COST]
  , tmp.[HH_COST]
  , tmp.[VAR_COST]
  , tmp.[LSTUPDATE]
FROM [RX_Billing].[dbo].[FS_Drug] drug
RIGHT OUTER JOIN [RX_Billing].[dbo].[FS_Drug_TEMP] tmp 
    ON  drug.[TRADENAME] = tmp.[TRADENAME]
WHERE drug.[TRADENAME] IS NULL 

Вы также можете удалить или пометить как удаленные записи в препарате, которых больше нет в tmp. Сделайте это отдельным оператором, аналогичным UPDATE, но с LEFT OUTER JOIN, где tmp.TRADENAME равно NULL.

3 голосов
/ 26 февраля 2009

Вы можете попробовать сделать UPSERT (что в основном означает «если существует, обновите, иначе вставьте»).

Я полагаю, что SQL-сервер вызывает его MERGE

2 голосов
/ 26 февраля 2009

Не хотите ли вы сделать INSERT для новых строк и UPDATE для существующих строк? Обновление этого до ВНУТРЕННЕГО СОЕДИНЕНИЯ и добавление отдельного ВСТАВКИ должно решить вашу проблему, если я правильно понимаю.

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