![在此输入图像描述] [1]我创建了一个触发器,每当我将信息插入表格时,我会计算总行数并打印新添加的行。这是我的代码:
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;
/
但是,我收到编译错误,说“预期到了条款”,请问有什么问题?
答案 0 :(得分:1)
首先,您不能拥有只执行SELECT
的PL / SQL块。您需要对数据执行某些操作。如果您希望查询恰好返回1行,请执行SELECT INTO
。如果您希望查询返回多于1行,则需要打开要迭代的游标。
其次,在行级触发器中,通常无法查询表本身。你通常会得到一个变异表异常(在某些特殊情况下你可以这样做,但这会严重限制你的灵活性,所以应该避免这种情况)。要获取行级信息,只需使用:new
伪记录中的各个列。为了获得计数,您实际上想要使用语句级触发器。根据Oracle版本,您可以创建具有行级和语句级组件的复合触发器。
第三,在仅在插入操作上定义的触发器中使用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;
答案 1 :(得分: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;
/
我建议你给你的变量命名不同于你的列。它可能会使代码混淆阅读...