2012-03-30 85 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