Sql Oracle查询是否仅显示更改的记录?

Sql Oracle查询是否仅显示更改的记录?,sql,oracle,audit,Sql,Oracle,Audit,有没有什么巧妙的方法可以在Oracle中创建一个SQL语句,只显示已更改的字段?我们有一个数据表和一个相关的审计表,具有相同的字段名。我可以在适当的关键字段上加入它们,然后我可以单独检查每个字段的更改,如下所示: SELECT t.FIELD1, a.FIELD1 AUDIT_FIELD1, t.FIELD2, a.FIELD2 AUDIT_FIELD2, t.FIELD3, a.AUDIT_FIELD3, etc ...

有没有什么巧妙的方法可以在Oracle中创建一个SQL语句,只显示已更改的字段?我们有一个数据表和一个相关的审计表,具有相同的字段名。我可以在适当的关键字段上加入它们,然后我可以单独检查每个字段的更改,如下所示:

    SELECT
    t.FIELD1,
    a.FIELD1 AUDIT_FIELD1,
    t.FIELD2,
    a.FIELD2 AUDIT_FIELD2,
    t.FIELD3,
    a.AUDIT_FIELD3,
    etc
    ...
    FROM
    DATA_TABLE t
    INNER JOIN
    AUDIT_TABLE a
    ON
    a.EMP_ID = t.EMP_ID
    ...
    WHERE 
    a.FIELD1 <> t.FIELD1
    OR
    a.FIELD2 <> t.FIELD2
    OR
    a.FIELD3 <> t.FIELD3
    etc etc..
选择
t、 字段1,
a、 现场1审计(现场1),
t、 字段2,
a、 领域2审计领域2,
t、 字段3,
a、 审计领域3,
等
...
从…起
数据表t
内连接
审计单位表a
在…上
a、 EMP_ID=t.EMP_ID
...
哪里
a、 FIELD1 t.FIELD1
或
a、 Field2T.FIELD2
或
a、 字段3 t.FIELD3
等等。。
最后我得到X行,每行至少有一个改变的字段,但我必须仔细观察结果,找出哪些字段改变了

似乎我应该能够进行某种查询,基本上说“对于表中的每个字段,如果它与另一个表不匹配,则显示字段名称和值。”


所有这些都需要在SQL中完成,因为公司要求我们使用一个单独的查询/报告工具,该工具不能在Oracle后端数据库上创建任何对象(表、视图、触发器、SP等)。

是否需要以下工作?它将指示哪些字段已更改为每个字段的Y/N列,因为多个字段可能已更改

SELECT 
    CASE WHEN a.FIELD1 <> t.FIELD1 THEN 'Y' ELSE 'N' END AS FIELD1CHANGED,
    CASE WHEN a.FIELD2 <> t.FIELD2 THEN 'Y' ELSE 'N' END AS FIELD2CHANGED,
    CASE WHEN a.FIELD3 <> t.FIELD3 THEN 'Y' ELSE 'N' END AS FIELD3CHANGED,
...
选择
当a.FIELD1 t.FIELD1然后“Y”或“N”结束为FIELD1更改时,
当a.FIELD2 t.FIELD2然后“Y”或“N”结束为FIELD2更改时,
当a.FIELD3 t.FIELD3然后“Y”或“N”结束为FIELD3更改时,
...

一种更传统的方法是自己进行审计。在表上添加一个触发器,使用伪代码

 when insert, update or delete for each row

 IF inserting then
 Insert into your_table_audit (fields) Values(:old.id,...,...'INSERT');
 Elsif updating then
 Case
 ..compare all field values to find changed values
 End
 Insert into your_table_audit (fields) Values(:old.id,...,...'Changed '||:old.value||' to '||:new.value);
 Else
 Insert into your_table_audit (fields) Values(:old.id,...,...'DELETE');

这可以封装在一个包中,并对任何表应用一些工作。您必须从Oracle元数据中访问列的名称,然后在运行时使用动态SQL构建代码。

检查这是否有用

create table tab1 (
col1 varchar(10),
col2 varchar(10),
col3 Number(10)
);

insert into Tab1 values ('xxx','xxx',99);
insert into Tab1 values ('aaa','aaa',98);
insert into Tab1 values ('bbb','bbb',97);

create table tab2 (
col1 varchar(10),
col2 varchar(10),
col3 Number(10)
);

insert into Tab2 values ('xxx','xxx',99);
insert into Tab2 values ('aaaA','aaa',98);
insert into Tab2 values ('bbb','bbbB',97);

commit;

select col1,col2,col3 from tab2
minus 
select col1,col2,col3 from tab1

---------- ---------- ----------------------    
COL1       COL2       COL3                   
---------- ---------- ---------------------- 
aaaA       aaa        98                     
bbb        bbbB       97     


--drop table tab1;
--drop table tab2;

您好,请勾选“减号”运算符,这可能很有用。在这种情况下,当这种技术起作用时,我已经尝试过了,但它仍然意味着为每个特定的列编码,并且返回没有变化的列。理想情况下,我希望只显示已更改的列…而不必将每一列编码为实际的SQL,如果可能的话…我认为这可能是一种在内存中创建某种临时表的方法,某种方式可以查询为“对于诱惑中的每一列…”但我不是一个足够高级的Oracle SQL程序员,不知道是否/如何做这样的事情。@Brian您可以使用PL/SQL中的动态查询来做这件事。但不是在普通SQL中。你在寻找什么吗