DB2 更新和插入触发器,引用了很多字段,我可以使用 * 来缩短它们(在 iSeries 中,但可能并不重要)
iSeries 上的 DB2 与其他平台上的 DB2 略有不同,但正如我所说,这可能并不重要。
这是我的以下触发器(有效)(一个区别是使用“/”与“.”,具体取决于用于创建查询的工具)
create trigger utbachInsert after insert on CO99PR/UTBACH
referencing new as n
for each row mode db2sql
begin atomic
insert into CO99PRH/UTBACH values(
n.BCGRP, n.BCID,n.BCSTAT,n.BCDESC,n.YYRGDT,
n.MMRGDT,n.DDRGDT,n.YY1EDT,n.MM1EDT,n.DD1EDT,
n.YYBLDT,n.MMBLDT,n.DDBLDT,n.YYPSDT,n.MMPSDT,
n.DDPSDT,n.YYPGDT,n.MMPGDT,n.DDPGDT,n.BCCOMM,
n.BCUSER,n.YYDATE,n.MMDATE,n.DDDATE
);
end
create trigger utbachUpdate after update on CO99PR/UTBACH
referencing new as n
for each row mode db2sql
begin atomic
update CO99PRH/UTBACH set
BCGRP = n.BCGRP,
BCID = n.BCID,
BCSTAT = n.BCSTAT,
BCDESC = n.BCDESC,
YYRGDT = n.YYRGDT,
MMRGDT = n.MMRGDT,
DDRGDT = n.DDRGDT,
YY1EDT = n.YY1EDT,
MM1EDT = n.MM1EDT,
DD1EDT = n.DD1EDT,
YYBLDT = n.YYBLDT,
MMBLDT = n.MMBLDT,
DDBLDT = n.DDBLDT,
YYPSDT = n.YYPSDT,
MMPSDT = n.MMPSDT,
DDPSDT = n.DDPSDT,
YYPGDT = n.YYPGDT,
MMPGDT = n.MMPGDT,
DDPGDT = n.DDPGDT,
BCCOMM = n.BCCOMM,
BCUSER = n.BCUSER,
YYDATE = n.YYDATE,
MMDATE = n.MMDATE,
DDDATE = n.DDDATE;
end
简单地在上面的块中我需要输入很多内容,我很漂亮当然,我已经使用了 select 语句来获取其他插入触发器所需的条目,并且因为它是一个 select 语句,所以我可以使用 table1.* (它加入了另一个表)。由于 n 引用了旧行,我希望我可以说 n.* 或类似的内容。
如果您知道无法做到这一点,我将需要在很多地方这样做,我会很乐意接受这个答案。
PS:有时了解上下文会有所帮助,我正在为一组表格执行此操作,以保持其内容同步(很好地在一个方向上)。这些表由使用记录级访问的程序使用(在 DB2 上使用 SQL 之前),更改表通常意味着重新编译使用它们的程序(删除或添加行、添加引用约束,甚至添加触发器)修改此类程序中的数据并将其放入相同的表中已被证明会导致问题,并且系统管理员不想重新编译这些程序),因此必须将所有表值复制到新表中,这些表可以然后像我们一样使用预计不会有太大影响。这允许一定程度的解耦,并让我们在如何管理模式方面有一些喘息的空间。
DB2 on iSeries is a little different then DB2 than other platforms but like I said it might not matter.
Here are my following triggers (which work) (One difference is the use of '/' vs '.' depending on what tool is used to create the query)
create trigger utbachInsert after insert on CO99PR/UTBACH
referencing new as n
for each row mode db2sql
begin atomic
insert into CO99PRH/UTBACH values(
n.BCGRP, n.BCID,n.BCSTAT,n.BCDESC,n.YYRGDT,
n.MMRGDT,n.DDRGDT,n.YY1EDT,n.MM1EDT,n.DD1EDT,
n.YYBLDT,n.MMBLDT,n.DDBLDT,n.YYPSDT,n.MMPSDT,
n.DDPSDT,n.YYPGDT,n.MMPGDT,n.DDPGDT,n.BCCOMM,
n.BCUSER,n.YYDATE,n.MMDATE,n.DDDATE
);
end
create trigger utbachUpdate after update on CO99PR/UTBACH
referencing new as n
for each row mode db2sql
begin atomic
update CO99PRH/UTBACH set
BCGRP = n.BCGRP,
BCID = n.BCID,
BCSTAT = n.BCSTAT,
BCDESC = n.BCDESC,
YYRGDT = n.YYRGDT,
MMRGDT = n.MMRGDT,
DDRGDT = n.DDRGDT,
YY1EDT = n.YY1EDT,
MM1EDT = n.MM1EDT,
DD1EDT = n.DD1EDT,
YYBLDT = n.YYBLDT,
MMBLDT = n.MMBLDT,
DDBLDT = n.DDBLDT,
YYPSDT = n.YYPSDT,
MMPSDT = n.MMPSDT,
DDPSDT = n.DDPSDT,
YYPGDT = n.YYPGDT,
MMPGDT = n.MMPGDT,
DDPGDT = n.DDPGDT,
BCCOMM = n.BCCOMM,
BCUSER = n.BCUSER,
YYDATE = n.YYDATE,
MMDATE = n.MMDATE,
DDDATE = n.DDDATE;
end
Simply in the above blocks I need to type a lot, I'm pretty sure I've used a select statement to get the entries I need for an other insert trigger and because it was a select statement I could use table1.* (it joined another table). Since n references the old row I was hoping I could say n.* or something like that.
I'll need to do this in a lot of places if you know it can not be done, I'll gladly accept that as an answer.
PS: Sometimes it helps to have context, I'm doing this for a set of tables to keep their contents in sync (well in one direction). The tables are used by programs which use record level access (before SQL was used on DB2) and changing the tables often means recompiling the programs which make use of them (dropping or adding a row, adding a referential constraint, and even adding a trigger which modifies the data from such a program and places it in the SAME table has been shown to cause issues and the system admin does not want to recompile these programs), so all the table values must be copied to the new tables, these tables can then be used as we'd expect without having much impact. This allow a certain amount of decoupling and lets us have some breathing room with regard to how we may manage the schema.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在查询中使用
SELECT *
格式从来都不是一个好主意(临时开发运行或视图除外 - 应将其视为与 API 相同)。特别是当将数据从一个文件移动到另一个文件时 - 如果更改源文件,但不更改(有意或无意)目标文件,会发生什么情况?
我不知道从物理文件添加/删除触发器会导致级别检查错误(意味着程序需要重新编译)。如果您更改文件的定义,因此需要更改触发器,则无论如何您都需要重新编译程序(因为这确实更改了签名)。
如果你们真的对更新底层架构感兴趣,首选方法是定义视图(而不是复制表),并使用 SQL 查询视图。这样做将完全(据我所知)消除 RPG/RPGLE 程序通过 PF 更改重新编译的需要(尽管更改视图将意味着需要更新......)
It's never a good idea to use the
SELECT *
format in queries (except ad-hoc dev-run, or with views - which should be considered the same as an API).Especially when moving data from one file to another - what happens if you change the origin file, but don't change (deliberately or accidentally) the destination file?
I'm not aware of anything where adding/removing a trigger from a physical file causes level-check errors (meaning the program would need to be recompiled). If you change the definition of the file, and thus need to change the trigger, you'd need to recompile program anyways (because that does change the signature).
If you guys are really interested in being able to update the underlying schema, the preferred method is defining views (not replicated tables), and querying the views with SQL. Doing so will completely (as far as I'm aware) remove the need for RPG/RPGLE programs to be recompiled with PF changes (although changing a view will mean that things need to be updated...)