2014-11-20 145 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