直接进入。我们有表 (TABLE) 和审计表 (AUDITTABLE) 存储对主表的更改。
在表中,我们有如下条目:
身份证 | 姓名 | 已创建 | 位置ID | 人员ID |
---|---|---|---|---|
1 | 犹他州 | 94年1月1日 | 35 | 1 |
2 | 俄亥俄州 | 95/02/01 | 42 | 5 |
将第 1 行的
LocationID
从 35 更改为 50,并将 PersonID
从 1 更改为 3 将记录在审核表中(为简洁起见,省略了一些列,还有诸如创建和创建者之类的项目来跟踪何时和由谁更改了值):
身份证 | 来源ID | 钥匙 | 旧值 |
---|---|---|---|
1 | 1 | 位置ID | 35 |
2 | 1 | 人物 | 1 |
我正在编写一个查询,从审计表中提取数据:
SELECT
sourceid AS ID,
id AS EVENT_ID
key AS COLUMN,
oldvalue AS PREVIOUS_ENTRY
FROM
AUDITTABLE
我想要在 select 中使用一个子查询,根据当前行的审计表中的 KEY(与主表列名称一对一匹配)来提取主表中当前存储的值。 我可以使用 Case 语句来完成此操作,但我有大约 100 个表来执行此操作,每个表都有唯一的列名(每个表有几十个列),这将是一场噩梦。
编辑
写完这篇我正在看推荐文章,似乎一切都指向写案例陈述。 如果这就是最终的答案,请让我知道这无法以我需要的方式实现,并且无需浪费时间编写示例案例陈述或联合查询 - 这完全符合我的技能范围,尽管这会带来身体上的痛苦接下来
我在想类似下面的东西(这显然不起作用,但显示了我想要实现的目标的总体思路)。
SELECT
sourceid AS ID,
id AS EVENT_ID
key AS COLUMN,
oldvalue AS PREVIOUS_ENTRY,
(SELECT TABLE. || (SELECT TEMPAUDITTABLE.KEY
FROM AUDITTABLE AS TEMPAUDITTABLE
WHERE TEMPAUDITTABLE.SOURCEID = AUDITTABLE.SOURCEID)
FROM Table
WHERE Table.ID = Audittable.sourceid) AS Current_Value
FROM
AUDITTABLE
我知道您可以从
USER_TAB_COLUMNS
获取表列名称,这可能是解决方案的一部分,但我不知道如何实现类似的东西。
如果我遗漏了一些明显的东西,我提前道歉。我在编写查询方面相当不错,但我大约 90% 是自学的,我的知识可能存在一些差距。
对于任何愿意帮助我指出正确方向的人,谢谢!
我尝试过谷歌、copilot、tech-on-the-net,并搜索堆栈溢出问题。我还参考了 SQL Oracle 的文档。
为了使其通用,您需要使用动态 SQL。最简单的方法是一个简单的函数,它返回给定表、行和列的值。
create or replace function current_value(in_table_name in varchar2,in_row_column in varchar2, in_row_id in integer,in_select_column in varchar2)
return varchar2
as
var_result varchar2(4000);
begin
execute immediate 'select max('||in_select_column||') from '||in_table_name||' where '||in_row_column||' = :id' into var_result using in in_row_id;
return var_result;
end;
为了获得良好的性能,您需要确保行标识列在每个表中都建立了索引。然后你只需查询:
SELECT
sourceid AS ID,
id AS EVENT_ID
key AS COLUMN,
oldvalue AS PREVIOUS_ENTRY,
current_value('MYTABLE','MY_ID_COL',id,key) current_value
FROM AUDITTABLE