gpt4 book ai didi

oracle - 按名称获取 Oracle PL/SQl 变量属性(PL/SQL 中的反射)

转载 作者:行者123 更新时间:2023-12-01 14:34:35 27 4
gpt4 key购买 nike

我需要对更新行进行一些审核。

所以我有一个函数,它接收 some_table%ROWTYPE 类型的参数,其中包含要为该行保存的新值。

我还需要在历史表中保存一些有关更改的列值的信息。我正在考虑从 all_tab_columns 获取 some_table 的列名称,然后迭代这些列名称以比较新旧值并查看它是否已更改。问题是一旦我有了列名,我不知道如何访问 ROWTYPE 变量中的值。类似于 var.getProperty(columnName)。

我想这样做是为了避免有一堆 IF,每个字段一个,而且它也可以直接在表中添加新列。

而且我也不能使用触发器,因为上级说“没有触发器!”。 (如果这确实是唯一的办法,我可以尝试再次与他们讨论此事)。

最佳答案

也许值得找出为什么有“无触发器”规则。

有很多反对触发器的好论据 - 特别是关于将业务规则放入触发器 - 但日志记录通常被认为是使用触发器的一个很好的案例。

Oracle 的内置表版本控制(每次更新记录一行)也值得一看 - 这使历史记录的形状与当前表的形状保持一致。它不会为您提供“更改内容”历史记录,但最好在查看历史记录时立即执行“更改内容”,而不是在每次更新时增加成本。

我发现做类似你想要的事情的唯一方法 - 动态访问 %ROWTYPE 的属性,是将一个变量放在包头上(因此它是公开可见的),然后执行动态 PL/SQL。您可以封装行变量,只要动态 pl/sql block 在每次检查之前包含本地副本即可。即,将其想象为立即执行的模板。

DECLARE
lNew myTab%ROWTYPE;
lOld myTab%ROWTYPE;
lReturn PLS_INTEGER := 0;
BEGIN
lNew := pStatefulPackage.NewRow;
lOld := pStatefulPackage.OldRow;
IF NVL(lNew.<variable>,'~') != NVL(lOld..<variable>,'~') THEN
:lReturn := 1;
END IF;
END;

解决无法在动态 SQL 中绑定(bind)记录变量或 bool 值这一事实会带来很多麻烦。

它还增加了每列的大量开销。

最后,我发现 ALL_TAB_COLUMNS 太慢,无法用于此类事情 - 您需要将元数据缓存在本地 pl/sql 内存中。

关于oracle - 按名称获取 Oracle PL/SQl 变量属性(PL/SQL 中的反射),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3707940/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com