简体   繁体   中英

SQL Server: Insert if doesn't exist, else update and insert in another table

I'm inserting new records into a Person table, and if there's already a record with the same SSN, I want to backup this old record to another table (let's call it PersonsBackup) and update the row with my new values. There is an identity column in Person table that serves as my primary key, which has to be the same.

Source table structure:

Name | Addr | SSN

Person table structure:

PrimaryKeyID | Name | Addr | SSN

PersonBackup table structure:

BackupKeyID | Name | Addr | SSN | OriginalPrimaryKeyID

where OriginalPrimaryKeyID = PrimaryKeyID for the record that was backed up. How can this be done? I was thinking of using cursor to check if SSN matches, then insert that record accordingly, but I've been told that using cursors like this is very inefficient. Thanks for your help!

You can do so like this, combine the insert/update using MERGE

INSERT INTO PersonBackup
SELECT P.Name, P.Addr, P.SSN, P.PrimaryKeyID
FROM Person P
INNER JOIN source s ON P.SSD = s.SSD

MERGE Person AS target
USING (SELECT Name, Addr, SSN FROM SOURCE) AS source (NAME, Addr, SSN)
ON (target.SSN = source.SSN)
WHEN MATCHED THEN   
    UPDATE SET name = source.name, Addr = source.Addr
WHEN NOT MATCHED THEN
    INSERT(Name, Addr, SSN)
    VALUES(source.name, source.addr, source.SSN)

Here is some pseudocode to get you started:

  1. Insert into PersonBackup table all Person data where SSN joins to Source data
  2. Insert into Person table all Source data where SSN doesn't join to Person data
  3. Update Person table all Source data where SSN joins to Person Data

So some hints:

  • Figure out a query that returns Person data where SSN is in the Source data.
  • Figure out a query that returns Source Data where SSN isn't in Person data.
  • Check out the syntax for INSERT INTO.
  • Check out the syntax for UPDATE FROM.

Assuming that BackupKeyID is identity in the PersonBackup table, you may try update statement with the output clause followed by insert of the records not existing in the target table:

update p
set p.Name = s.Name, p.Addr = s.Addr
output deleted.Name, deleted.Addr,
    deleted.SSN, deleted.PrimaryKeyID into PersonBackup
from Source s
    join Person p on p.SSN = s.SSN;

insert into Person (Name, Addr, SSN)
select s.Name, s.Addr, s.SSN
from Source s
where not exists (select 1 from Person where SSN = s.SSN);

or using insert into ... from (merge ... output) construct in a single statement:

insert into PersonBackup
select Name, Addr, SSN, PrimaryKeyID
from
(
    merge Person p
    using (select Name, Addr, SSN from Source) s
    on p.SSN = s.SSN
    when matched then
        update set p.Name = s.Name, p.Addr = s.Addr
    when not matched then
        insert (Name, Addr, SSN) values (s.Name, s.Addr, s.SSN)
    output $action, deleted.Name, deleted.Addr, deleted.SSN, deleted.PrimaryKeyID)
as U(Action, Name, Addr, SSN, PrimaryKeyID)
where U.Action = 'UPDATE';
DECLARE @TEMP TABLE (SSN VARCHAR(100),Name VARCHAR(MAX),Addr VARCHAR(MAX) ), 
 @SSN VARCHAR(100), 
 @Name VARCHAR(MAX),
 @ADDR VARCHAR(MAX)

//INSERT YOUR VALUES INTO THIS TEMP VARIABLE FIRST. 


SET @SSN = (SELECT SSN FROM @TEMP)
SET @Name = (SELECT NAME FROM @TEMP)
SET @Addr = (SELECT ADDR FROM @TEMP)


IF EXISTS (SELECT  1 FROM Person_table WHERE SSN = @SSN)
BEGIN

    //BACKUP FIRST
    INSERT INTO PersonBackup_table
    SELECT * FROM Person_table WHERE SSN = @SSN

    //UPDATE NEXT
    UPDATE A
    SET A.NAME = @NAME,
        A.ADDR = @ADDR
    FROM Person_table A
    WHERE A.SSN = @SSN


END
ELSE
BEGIN

    INSERT INTO Person_table VALUES @Name,@Addr,@SSN
END

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM