2014-11-20 144 views
0

!我在创建一个触发器,只要我将信息插入到表格中,就可以计算总行数并打印新添加的行。这里是我的代码:插入后触发错误

Create or replace trigger TR_everyInsert 
After INSERT On PERSONS 
For each row 

Declare 
rowNumber int; 
PERSON_NAME varchar(30); 
gender varchar(30); 
color varchar(30); 

Begin 
select PERSON_NAME,GENDER,COLOR 
From PERSONS 
Where PERSON_NAME=:new.PERSON_NAME; 

select count(*) as rowNumber 
from PERSONS; 

if inserting then 
DBMS_OUTPUT.PUT_LINE ('There are ' || To_CHAR(rowNumber)); 
DBMS_OUTPUT.PUT_LINE ('New added info is ' || PERSON_NAME || 'with gender ' || 
GENDER || 'with color ' || color); 
end if; 

end; 
/

但是,我得到编译错误说“进入子句预期”,请问是什么问题?

回答

1

首先,你不能有一个只执行SELECT的PL/SQL块。你需要对数据做些什么。如果您希望查询完全返回1行,请执行SELECT INTO。如果您希望查询返回多于一行,您希望打开您要迭代的游标。

其次,在行级触发器中,通常不能查询表本身。你通常会得到一个变异表异常(有一些特殊情况你可以做到这一点,但这严重限制了你的灵活性,所以这是应该避免的)。要获得行级信息,只需使用:new伪记录中的各列。为了计算,你实际上想要使用语句级触发器。根据Oracle版本的不同,您可以创建具有行级和语句级组件的复合触发器。

第三,t只在插入操作中定义的触发器中有一个IF inserting语句没有意义。如果你的触发器是在多个操作中定义的(比如说INSERT OR UPDATE),并且你想根据哪个操作触发触发器来做一些不同的事情,那么只有这样做才有意义。

最后,你会希望你的本地变量被命名为不同于任何列的名称的东西。大多数人采用某种命名约定来消除局部变量的歧义,打包全局变量和列名称中的参数。我更喜欢本地变量,包全局变量和参数的前缀l_g_p_,这是Oracle社区中相当常见的约定。你可能更喜欢别的东西。

喜欢的东西

-- A row-level trigger prints out the data that is being inserted 
Create or replace trigger TR_everyInsert_row 
    After INSERT On PERSONS 
    For each row 
Begin 
    DBMS_OUTPUT.PUT_LINE ('New added info is ' || :new.PERSON_NAME || 
         ' with gender ' || :new.GENDER || 
         ' with color ' || :new.color); 
end; 

-- A statement-level trigger prints out the current row count 
Create or replace trigger TR_everyInsert_stmt 
    After INSERT On PERSONS 
Declare 
    l_cnt integer; 
Begin 
    select count(*) 
    into l_cnt 
    from persons; 

    DBMS_OUTPUT.PUT_LINE ('There are ' || To_CHAR(l_cnt) || ' rows.'); 
end; 
+0

非常感谢您的回答。 – 2014-11-20 23:45:17

0

错误信息非常清楚。您需要将您的两个查询放入你声明的变量的结果:

Create or replace trigger TR_everyInsert 
After INSERT On PERSONS 
For each row 

Declare 
lv_rowNumber int; 
lv-_PERSON_NAME varchar(30); 
lv_gender varchar(30); 
lv_color varchar(30); 

Begin 
select PERSON_NAME,GENDER,COLOR 
into lv_person_name, lv_gender, lv_color 
From PERSONS 
Where PERSON_NAME=:new.PERSON_NAME; 

select count(*) into lv_rowNumber 
from PERSONS; 

if inserting then 
DBMS_OUTPUT.PUT_LINE ('There are ' || To_CHAR(rowNumber)); 
DBMS_OUTPUT.PUT_LINE ('New added info is ' || PERSON_NAME || 'with gender ' || 
GENDER || 'with color ' || color); 
end if; 

end; 
/

我会建议你给你的变量比你的列不同的名称。它可能会使代码混淆阅读...

+0

当然,这很可能会抛出一个变异表例外,一旦语法问题得到解决。 – 2014-11-20 23:21:02

+0

感谢您的回复 – 2014-11-20 23:43:58