Informix触发器更改插入的值

时间:2014-01-27 12:15:43

标签: informix eventtrigger

我想在插入之前更改几个列值。 我使用Informix作为数据库。

我有一个由3列组成的表:名称(NVARCHAR),类型(INT),计划(NVARCHAR)。

每次插入新记录时,我都想在插入之前检查Name值。如果名称以F开头,我想将Type值设置为1,将Plan Name设置为“Test”

简而言之,我想让触发器做的是:

  1. 对于每次新插入,首先检查名称值是否以F开头。
  2. 如果是,请将类型和计划设置为1,然后将“测试”设置为插入。
  3. 如果不是,请按原样插入值。
  4. 我已经用BEFORE和AFTER查找了CREATE TRIGGER语句。但是,我想有一个更清楚的例子。我的情况可能会涉及BEFORE。

3 个答案:

答案 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
;