2014-04-18 21 views
1

我想寫一個觸發器來檢測用戶名何時包含非法字符串(如淫穢)。Oracle觸發器不執行 - INSTR函數問題

我有兩個小表:播放器和IllegalWords,其中IllegalWords包含用戶名將被檢查的詞。

我使用Oracle版本11g R2在www.sqlfiddle.com上測試了代碼。

當用戶名與非法單詞相匹配時(包括字母外殼,即小型大寫字母/大寫字母不同的情況),觸發器起作用。但是,當非法單詞是用戶名的子字符串時,它會失敗。例如,它不能檢測到悲傷的小丑包含小丑。

我不明白爲什麼,因爲我使用了INSTR函數。

誰能幫我理解嗎?

謝謝

LC

CREATE TABLE Player (
    PlayerID INT, 
    UserName CHAR(100), 
    IsLocked CHAR(1) DEFAULT 0 
)/ 

CREATE TABLE IllegalWords 
(
    Word CHAR(100) 
)/ 


INSERT INTO Player 
VALUES (1, 'John Doe', 0)/ 

INSERT INTO Player 
VALUES (2, 'Paris Hilton', 0)/ 

INSERT INTO Player 
VALUES (3, 'Krusty', 0)/ 

INSERT INTO Player 
VALUES (4, 'Pierrot', 0)/ 

INSERT INTO IllegalWords 
VALUES ('clown')/ 


CREATE OR REPLACE TRIGGER CheckIllegalName 
AFTER INSERT OR UPDATE OF UserName ON Player 
BEGIN 
    FOR r1 in (SELECT UserName FROM Player) 
    LOOP 
     FOR r2 in (SELECT Word FROM IllegalWords) 
     LOOP 
      IF (INSTR(LOWER(r1.UserName), LOWER(r2.Word)) != 0) THEN 
       UPDATE Player SET IsLocked = 1 WHERE UserName = r1.UserName; 
      END IF; 
     END LOOP; 
    END LOOP; 
END CheckIllegalName; 
/

UPDATE Player 
SET UserName = 'clown' 
WHERE PlayerID = 1/ 

UPDATE Player 
SET UserName = 'Clown' 
WHERE PlayerID = 2/ 


UPDATE Player 
SET UserName = 'sadclown' 
WHERE PlayerID = 3/ 

UPDATE Player 
SET UserName = 'clown_is_sad' 
WHERE PlayerID = 4/ 

SELECT * FROM Player/ 

結果:

PLAYERID, USERNAME, ISLOCKED 
1, clown, 1 
2, Clown, 1 
3, sadclown, 0 
4, clown_is_sad, 0 
+0

看起來像一個sqlfiddle中的錯誤。您是否在實際的Oracle數據庫上試過這段代碼? – wvdz

+0

我在實際的數據庫(版本9.2)上嘗試了相同的代碼,結果是一樣的。 – lcazarre

回答

3

的問題是數據類型的Word:

CREATE TABLE IllegalWords 
(
    Word CHAR(100) 
)/ 

我不是肯定爲什麼,因爲文檔說CHAR應該可以工作,但是如果我有機會將數據類型轉換爲VARCHAR2,它就可以工作。

+0

太棒了!有用。我永遠不會自己找到這個。我非常感謝你的幫助。 – lcazarre

+0

@Icazarre:CHAR字段在右側自動空白填充字段的全部寬度。 VARCHAR2只存儲給定的字符。所以當'Krusty'被存儲在CHAR(20)中時,「Krusty」+14空白是在現場記錄的。存儲在VARCHAR2(20)字段中的相同值是沒有空白填充的「Krusty」。 [SQLFiddle here](http://www.sqlfiddle.com/#!4/fc896/2)。 [Documentation here](http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1821)。一般來說,使用VARCHAR2--它會爲你節省很多悲傷和不眠之夜。分享並享受。 –