Sql 更新后记录的旧值和新值

Sql 更新后记录的旧值和新值,sql,oracle,plsql,Sql,Oracle,Plsql,我需要创建一个存储过程,它将找出更新记录的旧值和新值。 它应该包括用于在运行时查找列名的动态查询 我正在使用oracle 12C进行此操作 create table student ( id number(6) primary key, name varchar2(50), city varchar2(50), address varchar2(100), createdDateTime date, updatedDatetime date

我需要创建一个存储过程,它将找出更新记录的旧值和新值。 它应该包括用于在运行时查找列名的动态查询

我正在使用oracle 12C进行此操作

create table student (    
    id number(6) primary key,
    name varchar2(50),
    city varchar2(50),
    address varchar2(100),
    createdDateTime date,
    updatedDatetime date
);

insert into student values(1,'abc1','abc1','abc1','09-Jan-20','12-Jan-20');
insert into student values(2,'pqr','pqr','pqr','09-Jan-20',null);
学生桌-

ID      Name    City     Address    Create_time UpdatedTime
1       abc1    abc1     abc1       09-Jan-20   12-Jan-20
2       pqr     pqr      pqr        09-Jan-20   null

create table studentHistory (
    id number(6) ,
    name varchar2(50),
    city varchar2(50),
    address varchar2(100),
    DatetimeCreated date
);

insert into StudentHistory values(1,null,'abc',null,'10-Jan-20');
insert into StudentHistory values(1,'abc',null,null,'11-Jan-20');
insert into StudentHistory values(1,null,null,'abc','12-Jan-20');
学生历史表-

ID  Name    City        Address DatetimeCreated
1   null    abc          null     10-Jan-20
1   abc     null         null     11-Jan-20
1   null    null         abc      12-Jan-20
所需输出-->


我同意@stickybit。填充历史记录表实际上是一个起点。您应该创建@Littlefoot提到的触发器,以便在历史记录表中进行更新/插入,可以使用merge

但我只是根据您提供的数据尝试了一些东西,不要认为这是您要寻找的,但仍将其张贴在此处,因为它可能会在将来帮助其他人:

with name_cte
as
(
select 
a.id,
a.name as new_value,
b.name as old_value,
b.datetimecreated,
'name' as column_name
from student a
join studenthistory b
on a.id=b.id
and b.name is not null
)
,city_cte
as
(
select 
a.id,
a.city as new_value,
b.city as old_value,
b.datetimecreated,
'city' as column_name
from student a
join studenthistory b
on a.id=b.id
and b.city is not null
)
,address_cte
as
(
select 
a.id,
a.address as new_value,
b.address as old_value,
b.datetimecreated,
'address' as column_name
from student a
join studenthistory b
on a.id=b.id
and b.address is not null
)
select 
a.id,
a.column_name,
a.old_value,
a.new_value,
a.datetimecreated as updatetime
from name_cte a
union all
select
b.id,
b.column_name,
b.old_value,
b.new_value,
b.datetimecreated as updatetime
from city_cte b
union all
select
c.id,
c.column_name,
c.old_value,
c.new_value,
c.datetimecreated as updatetime
from address_cte c

我同意@stickybit。填充历史记录表实际上是一个起点。您应该创建@Littlefoot提到的触发器,以便在历史记录表中进行更新/插入,可以使用merge

但我只是根据您提供的数据尝试了一些东西,不要认为这是您要寻找的,但仍将其张贴在此处,因为它可能会在将来帮助其他人:

with name_cte
as
(
select 
a.id,
a.name as new_value,
b.name as old_value,
b.datetimecreated,
'name' as column_name
from student a
join studenthistory b
on a.id=b.id
and b.name is not null
)
,city_cte
as
(
select 
a.id,
a.city as new_value,
b.city as old_value,
b.datetimecreated,
'city' as column_name
from student a
join studenthistory b
on a.id=b.id
and b.city is not null
)
,address_cte
as
(
select 
a.id,
a.address as new_value,
b.address as old_value,
b.datetimecreated,
'address' as column_name
from student a
join studenthistory b
on a.id=b.id
and b.address is not null
)
select 
a.id,
a.column_name,
a.old_value,
a.new_value,
a.datetimecreated as updatetime
from name_cte a
union all
select
b.id,
b.column_name,
b.old_value,
b.new_value,
b.datetimecreated as updatetime
from city_cte b
union all
select
c.id,
c.column_name,
c.old_value,
c.new_value,
c.datetimecreated as updatetime
from address_cte c

“我需要创建存储过程…”-不,您需要创建触发器,它们用于此目的。互联网上有无数的例子,做一些搜索,写一些代码。如果您无法使其正常工作,请返回-如果是,请编辑您的问题和您编写的post代码以及您遇到的错误。您应该将更新的旧值添加到历史记录表中。现在没有机会获得
更新的旧值,除非它是最后一个值。然后你只需要一个
选择
来获取旧值。“我需要创建存储过程…”-不,你需要创建一个触发器,它们用于这样的目的。互联网上有无数的例子,做一些搜索,写一些代码。如果您无法使其正常工作,请返回-如果是,请编辑您的问题和您编写的post代码以及您遇到的错误。您应该将更新的旧值添加到历史记录表中。现在没有机会获得
更新的旧值,除非它是最后一个值。然后,您只需选择
即可获得旧值。