2012-03-30 79 views
0

我在我的emp表中擁有唯一的主鍵。在SQL Server中更新或插入問題?

select * from EMP E; 

現在我已經創建emp_backup表這需要emp表一樣的備份。

insert into emp_backup 
select * from emp e 
where not exists (select EMPNO from emp_backup E1 where E1.EMPNO=e.EMPNO); 

上面的查詢成功地將所有的行從empemp_backup並確保當你再次上面的查詢它不會對現有行復制從emp在下次運行emp_backup表上運行。

現在我的問題是,當我更新emp表中的任何記錄,並嘗試運行上面的查詢時,它給我錯誤primary key violation這是例外。例如

update EMP 
set JOB='worker' 
where EMPNO=14; 

我複製紀錄empno 14 emp_backup表後更新emp表。

當我運行insert into emp_backup....查詢我希望此更新應該改爲emp_backup表。

我如何修改上述查詢,以便它將使用現有主鍵從empemp_backup複製更新的行。

我希望我的問題很明確,告訴我如何改善它。

+0

你有沒有定義的任何其他列作爲emp_backup – 2012-03-30 04:33:20

+0

唯一鍵或主鍵@SathyaNarayanan我只有'empno'作爲主鍵在這兩個'emp'和'emp_backup'表。 – 2012-03-30 04:34:03

+1

爲什麼你不使用備份?你可以使用全選以及差分選項... – 2012-03-30 04:34:53

回答

0

看來,當您創建emp_backup表,你還創建關於EMPNO表的表PK。這會阻止你插入兩次相同的emp記錄。

你需要重新思考你的「備份」計劃 - 你想

  1. 在表emp
  2. 表emp準確的鏡子每條記錄變化的每個版本上運行的審計?

在1:

  • 刪除上emp_backup表的主鍵。這將允許將重複的emp記錄複製到其中。如果您需要emp_backup表的冪等性,您可以創建一個新的代理PK(例如,emp_backup_id int identity(1,1),可能是一個新的CURRENT_TIMESTAMP拖欠列,以幫助您確定這是最新的

下降的PK後,更新的記錄可以「備份」爲:

insert into emp_backup 
select * from emp e 
where exists 
    (select EMPNO 
    from emp_backup E1 
    where E1.EMPNO=e.EMPNO 
    and 
    (e1.othercolumn1 <> e.othercolumn1 
    or e1.othercolumn2 <> e.othercolumn2 
    ... 
    ) 
); . 

(請注意,列某些類型不能直接進行比較)

爲2,您需要在您的emp_bak表更新現有的記錄:

update eb 
set eb.othercolumn1 = e.othercolumn1, 
    eb.othercolumn2 = e.othercolumn2 
from emp_backup eb 
    inner join emp e on eb.empno = e.empno 
where 
    eb.othercolumn1 <> e.othercolumn1 
    or eb.othercolumn2 <> e.othercolumn2 
    ... 
); . 

但你的表鏡像引出了一個問題,每次你想備份,爲什麼不乾脆放棄你現有的emp_backup表並做到:

insert into emp_backup 
select * from emp e 

+0

我無法刪除每次包含超過百萬條記錄的備份表。 – 2012-03-30 04:59:44

+0

在這種情況下,請使用觸發器進行審覈,如@Karl建議的那樣,否則只需將您的數據委託給像OMGPonies評論的備份。 – StuartLC 2012-03-30 05:08:40

1

爲了收集所有變更,您將需要一個歷史(或審計)表。在你的桌子上創建一個記錄器,用於寫入一條記錄,在每次更改時在活動時間字段中包含歷史記錄表。然後在活動時間字段大於上次備份查詢時從歷史記錄表中選擇。

thizs將使你能夠收集所有更新插入和刪除

0

由於您使用的是SQL Server 2008,因此可以使用MERGE命令。

這一個命令可以讓您在備份表中不存在的情況下添加記錄,並在記錄存在時將其更新爲匹配。

Here's an example from MSDN

MERGE emp_backup AS T 
USING emp AS S 
ON (T.EMPNO = S.EMPNO) 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT(EMPNO, JOB) VALUES(S.EMPNO, S.JOB) 
WHEN MATCHED 
    THEN UPDATE SET T.JOB = S.JOB