#sql #sql-server-2005 #upsert
#sql #sql-server-2005 #upsert
Вопрос:
У меня есть две таблицы:
NewNotes
MasterNotes
Каждый месяц NewNotes
таблица обновляется новыми примечаниями как для новых, так и для существующих учетных записей. Мне нужно либо обновить существующие заметки в MasterNotes
таблице, либо вставить новые заметки, если номер счета еще не указан в MasterNotes
таблице.
Обе таблицы имеют три столбца: REPORT
, ACCOUNT_NUMBER
, NOTES
.
Для обновления записи и номер счета, и отчет должны быть одинаковыми (в MasterNotes
таблице могут быть два разных номера счетов с двумя разными отчетами).
Кто-нибудь может помочь с этим?
Вот мое мышление до сих пор:
IF NOT EXISTS
(
SELECT REP, ACCOUNT_NUMBER
FROM MasterNotes
WHERE REP = (SELECT Report FROM NewNotes) AND
ACCOUNT_NUMBER = (SELECT AccountNo FROM NewNotes)
)
INSERT INTO MasterNotes
ELSE
UPDATE
Я знаю, что это неверно, потому что подзапрос возвращает более одного значения, но я не уверен, как это сделать строка за строкой.
Или, может быть, что-то вроде этого?
INSERT INTO MasterNotes
SELECT Report, AccountNo, A.Notes
FROM NewNotes A
LEFT OUTER JOIN MasterNotes B
ON A.Report = B.REP AND A.AccountNo = B.ACCOUNT_NUMBER
WHERE B.ACCOUNT_NUMBER IS NULL AND B.REP IS NULL
UPDATE MasterNotes
SET NOTE = B.Notes
FROM MasterNotes A, NewNotes B
WHERE A.ACCOUNT_NUMBER = B.AccountNo AND A.REP = B.Report
Комментарии:
1. Покажите нам, что вы уже пробовали! Мы будем рады помочь вам в решении любых проблем, но SO — это не сервис write my codez for me …. сначала вам нужно приложить некоторые усилия !
Ответ №1:
Вот несколько примеров, которые помогут вам начать работу. Я предоставил два способа выполнения обоих действий в SQL2005. Лично я предпочитаю методы объединения, но они, как было показано, немного медленнее, но я нахожу их более удобными для записи / чтения. Они находятся внутри, но закомментированы.
DECLARE @NewNotes TABLE (REPORT VARCHAR(10), ACCOUNT_NUMBER INT, NOTES VARCHAR(50))
DECLARE @MasterNotes TABLE (REPORT VARCHAR(10), ACCOUNT_NUMBER INT, NOTES VARCHAR(50))
INSERT INTO @MasterNotes (REPORT, ACCOUNT_NUMBER, NOTES)
SELECT 'ABC', 123, 'CUSTOMER IS VERY NICE, SOMETIMES...' UNION
SELECT 'DEF', 456, 'CUSTOMER IS ANGRY'
INSERT INTO @NewNotes (REPORT, ACCOUNT_NUMBER, NOTES)
SELECT 'ABC', 123, 'CUSTOMER IS VERY NICE' UNION
SELECT 'DEF', 456, 'CUSTOMER IS ANGRY' UNION
SELECT 'GHI', 789, 'CUSTOMER WANTS CALL BACK'
UPDATE M SET NOTES = N.NOTES
FROM @MasterNotes M, @NewNotes N
WHERE M.REPORT = N.REPORT
AND M.ACCOUNT_NUMBER = N.ACCOUNT_NUMBER
/** ALTERNATE UPDATE METHOD **/
--UPDATE M SET NOTES = N.NOTES
--FROM @MasterNotes M
--JOIN @NewNotes N
-- ON M.REPORT = N.REPORT
-- AND M.ACCOUNT_NUMBER = N.ACCOUNT_NUMBER
INSERT INTO @MasterNotes (REPORT, ACCOUNT_NUMBER, NOTES)
SELECT N.REPORT, N.ACCOUNT_NUMBER, N.NOTES
FROM @NewNotes N
WHERE NOT EXISTS (SELECT ACCOUNT_NUMBER FROM @MasterNotes M WHERE M.REPORT = N.REPORT)
/** ALTERNATE INSERT METHOD **/
--INSERT INTO @MasterNotes (REPORT, ACCOUNT_NUMBER, NOTES)
--SELECT N.REPORT, N.ACCOUNT_NUMBER, N.NOTES
--FROM @NewNotes N
--LEFT OUTER JOIN @MasterNotes M
-- ON N.REPORT = M.REPORT
-- AND N.ACCOUNT_NUMBER = M.ACCOUNT_NUMBER
--WHERE M.ACCOUNT_NUMBER IS NULL
SELECT *
FROM @MasterNotes
ПРИМЕЧАНИЕ: если вы когда-либо обновитесь до SQL2008 , вы можете использовать MERGE
функцию следующим образом:
DECLARE @NewNotes TABLE (REPORT VARCHAR(10), ACCOUNT_NUMBER INT, NOTES VARCHAR(50))
DECLARE @MasterNotes TABLE (REPORT VARCHAR(10), ACCOUNT_NUMBER INT, NOTES VARCHAR(50))
INSERT INTO @MasterNotes (REPORT, ACCOUNT_NUMBER, NOTES)
SELECT 'ABC', 123, 'CUSTOMER IS VERY NICE, SOMETIMES...' UNION
SELECT 'DEF', 456, 'CUSTOMER IS ANGRY'
INSERT INTO @NewNotes (REPORT, ACCOUNT_NUMBER, NOTES)
SELECT 'ABC', 123, 'CUSTOMER IS VERY NICE' UNION
SELECT 'DEF', 456, 'CUSTOMER IS ANGRY' UNION
SELECT 'GHI', 789, 'CUSTOMER WANTS CALL BACK'
MERGE INTO @MasterNotes AS DST
USING (SELECT REPORT, ACCOUNT_NUMBER, NOTES FROM @NewNotes) AS SRC
ON SRC.ACCOUNT_NUMBER = DST.ACCOUNT_NUMBER
WHEN MATCHED THEN UPDATE
SET DST.REPORT = SRC.REPORT,
DST.NOTES = SRC.NOTES
WHEN NOT MATCHED THEN
INSERT (REPORT, ACCOUNT_NUMBER, NOTES)
VALUES (SRC.REPORT, SRC.ACCOUNT_NUMBER, SRC.NOTES);
SELECT *
FROM @MasterNotes