我的emp
表中包含主键的唯一行。
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);
上述查询成功将所有行从emp
复制到emp_backup
,并确保当您再次运行上述查询时,它不会将现有行从emp
复制到{{1下一次运行中的表。
现在我的问题是当我更新emp_backup
表中的任何记录并尝试运行上面的查询时,它会给我emp
的错误,但不包括。
例如。
primary key violation
我将带有update EMP
set JOB='worker'
where EMPNO=14;
14的记录复制到emp_backup表后更新emp
表。
当我运行empno
查询时,我希望此更新更改应重新进入insert into emp_backup....
表。
如何修改上述查询,以便将包含现有主键的更新行从emp_backup
复制到emp
。
我希望我的问题很明确,告诉我如何改进它。
答案 0 :(得分:1)
为了收集所有更改,您需要一个历史(或审计)表。在您的表上创建一个triger,它将记录写入包含每个更改的历史记录表的活动时间字段。然后在活动时间字段大于上次备份查询时从历史表中选择。
thizs将使您能够收集所有更新插入和删除
答案 1 :(得分:0)
似乎在创建emp_backup表时,您还在EMPNO表上创建了表PK。这将阻止您两次插入相同的emp记录。
你需要重新考虑你的“备份”计划 - 你想要吗
1:
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
...
答案 2 :(得分:0)
由于您使用的是SQL Server 2008,因此可以使用MERGE命令。
这个命令将允许您在备份表中不存在时添加记录,并在它们存在时更新它们以匹配。
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