Обновить таблицу из временной таблицы
У меня есть таблица, в которой хранится информация о лекарствах из формуляра, которую необходимо ежедневно обновлять из центрального справочника. Временная таблица идентична таблице лекарств. Данные временной таблицы могут быть идентичны (и в большинстве случаев будут) основной таблице, либо в ней могут быть обновленные строки или новые строки.
У меня есть хранимая процедура для обновления основной таблицы, но она не работает, потому что не обновляет строки NULL (если во временной таблице есть новая строка).
Это 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]
РЕДАКТИРОВАТЬ:
Я пошел с кодом Рори. Спасибо, это прекрасно работает.
Примечание для Ориона Эдвардса: UPSERT / MERGE - это именно то, что я хотел, но он не поддерживается в SQL Server 2005. Очевидно, это было запланировано, но не было выпущено в этом выпуске. Он доступен в Server 2008. (Из того, что мне сообщили в Interwebs.)
Ответов (3)3
Стандартный способ - выполнить ОБНОВЛЕНИЕ, а затем ВСТАВИТЬ:
-- 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 IS NULL.