我想在插入之前更改几个列值。 我使用Informix作为数据库。
我有一个由3列组成的表:名称(NVARCHAR),类型(INT),计划(NVARCHAR)。
每次插入新记录时,我都想在插入之前检查Name值。如果名称以F开头,我想将Type值设置为1,将Plan Name设置为“Test”
简而言之,我想让触发器做的是:
我已经用BEFORE和AFTER查找了CREATE TRIGGER语句。但是,我想有一个更清楚的例子。我的情况可能会涉及BEFORE。
答案 0 :(得分:5)
@ user3243781的答案接近,但因为它返回错误而无效:
-747表或列匹配触发语句中引用的对象。
当触发的SQL语句作用于此时,将返回此错误 触发表,或两个语句都是更新时,以及列 在触发的操作中更新的内容与该列相同 触发语句更新。
所以替代方案是直接处理NEW变量。 为此,您需要使用带有 触发器引用 资源的过程,这意味着该过程将像self一样触发。
以下是我使用dbaccess在Informix v11.70上运行的示例 据我所知,此资源仅适用于引擎版本+11。
create table teste ( Name NVARCHAR(100), Type INT , Plan NVARCHAR(100) );
Table created.
create procedure check_name_values()
referencing new as n for teste ;;
define check_type integer ;;
define check_plan NVARCHAR ;;
if upper(n.name) like 'F%' then
let n.type = 1;;
let n.plan = "Test";;
end if
end procedure ;
Routine created.
;
create trigger trg_tablename_ins
insert on teste
referencing new as new
for each row
(
execute procedure check_name_values() with trigger references
);
Trigger created.
insert into teste values ('cesar',99,'myplan');
1 row(s) inserted.
insert into teste (name) values ('fernando');
1 row(s) inserted.
insert into teste values ('Fernando',100,'your plan');
1 row(s) inserted.
select * from teste ;
name cesar
type 99
plan myplan
name fernando
type 1
plan Test
name Fernando
type 1
plan Test
3 row(s) retrieved.
drop table if exists teste;
Table dropped.
drop procedure if exists check_name_values;
Routine dropped.
答案 1 :(得分:0)
create trigger trg_tablename_ins
insert on tablename
referencing new as new
for each row
(
execute procedure check_name_values
(
new.name,
new.type,
new.plan
)
);
create procedure check_name_values
(
name NVARCHAR,
new_type integer,
new_plan NVARCHAR,
)
define check_type integer ;
define check_plan NVARCHAR ;
let check_type = 1;
let check_plan = "Test";
if name = 'F%'
then
insert into tablename (name,type,plan) values (name,check_type,check_plan);
else
insert into tablename (name,type,plan) values (name,new_type,new_plan);
end if ;
end procedure ;
答案 2 :(得分:0)
这是我的版本,是对我在notifyix usenet组中找到的一个旧示例的改编。
可以更新触发器语句中的列,但不是很直接。您必须通过into
命令在execute procedure
语句中使用存储过程。
它在这里适用于IBM Informix Dynamic Server版本12.10.FC11WE。
drop table if exists my_table;
drop sequence if exists my_table_seq;
create table my_table (
id INTEGER
NOT NULL,
col_a char(32)
NOT NULL,
col_b char(20)
NOT NULL,
hinweis char(64),
uslu char(12)
DEFAULT USER
NOT NULL,
dtlu DATETIME YEAR TO SECOND
DEFAULT CURRENT YEAR TO SECOND
NOT NULL
)
;
create sequence my_table_seq
increment 1
start 1;
drop procedure if exists get_user_datetime();
create function get_user_datetime() returning char(12),datetime year to second;
return user, current year to second;
end function
;
drop trigger if exists ti_my_table;
create trigger ti_my_table insert on my_table referencing new as n for each row (
execute function get_user_datetime() into uslu, dtlu
)
;
drop trigger if exists tu_my_table;
create trigger tu_my_table update on my_table referencing new as n for each row (
execute function get_user_datetime() into uslu, dtlu
)
;
insert into my_table values (my_table_seq.nextval, "a", "b", null, "witz", mdy(1,1,1900)) ;
SELECT *
FROM my_table
WHERE 1=1
;