【发布时间】:2010-11-30 09:01:30
【问题描述】:
我想用另一列的聚合自动更新数据库列。 涉及三个表:
T_RIDER
RIDER_ID
TMP_PONYLIST
...
T_RIDER_PONY
RIDER_ID
PONY_ID
T_PONY
PONY_ID
PONY_NAME
...
T_RIDER 和 T_PONY 通过T_RIDER_PONY 具有 n:m 关系。
T_RIDER 和 T_PONY 有更多列,但这里只有 TMP_PONYLIST 和 PONY_NAME 相关。
TMP_PONYLIST 是PONY_NAMES 的分号分隔列表,想象一下"Twisty Tail;Candy Cane;Lucky Leaf"。
无论T_RIDER_PONY 或T_PONY 发生什么情况,我都希望此字段保持最新状态。
我的第一个想法是在T_RIDER_PONY 和T_PONY 上设置触发器。
问题是似乎不可能在触发器中读取T_RIDER_PONY,我总是得到ORA-04091。我发现了一些关于使用三个触发器和包变量的提示,但这听起来太复杂了。
也许您认为我最好更改架构或完全摆脱TMP_PONYLIST。
这些是选项,但不是这个问题的主题。
目前我只对不需要对我的应用程序进行任何更改的答案感兴趣(没有应用程序直接与表一起工作,只有视图,因此允许对视图进行欺骗)。
那么,我怎样才能让TMP_PONYLIST 自动保持最新状态?
如何连接字符串是一个有趣的子问题,我还没有找到一个优雅的解决方案。
我使用的是 Oracle Database 10g 企业版 10.2.0.4.0 - 64bi。
更新
我喜欢使用物化视图的想法。 我有的是:
CREATE MATERIALIZED VIEW
V_TMP_PONYLIST
BUILD IMMEDIATE
REFRESH COMPLETE ON COMMIT
AS SELECT
R.RIDER_ID, string_agg(P.PONY_NAME) AS TMP_PONYLIST
FROM
T_PONY P, T_RIDER R, T_RIDER_PONY RP
WHERE
P.PLOTGROUP_ID=RP.PLOTGROUP_ID AND
R.QUEUE_ID=RP.QUEUE_ID
GROUP BY R.RIDER_ID;
string_agg 未显示,因为它很长而且我认为它不相关。
它不能用ON COMMIT 编译,我得到ORA-12054。
据我了解,文档聚合仅禁止使用
REFRESH FAST,那么这里有什么问题?
更新 Vincents 和 Tonys 的答案不同,但都有帮助。 我接受了托尼,但也请务必阅读文森特的回答。
【问题讨论】:
-
我建议不要在单个列中存储多个值(“Twisty Tail;Candy Cane;Lucky Leaf”)...
标签: oracle triggers view ora-04091