2012-08-10 75 views
1

我想要一個簡單的SQL(觸發器)進行重複檢查。 我的表名是test1,有2列,codesname。在插入新記錄之前,請檢查記錄是否已經存在:如果存在,請生成錯誤並且不要插入;如果沒有,請繼續插入。Informix 4GL和觸發器

我該怎麼做?

+0

你有什麼嘗試,爲什麼它沒有工作?可以在[Informix 11.70信息中心](http://publib.boulder.ibm.com/infocenter/idshelp/v117/index.jsp)上找到這些手冊。爲什麼你需要一個觸發器,而不是簡單地在每一列上創建一個唯一的約束?除非需要,否則不要編寫觸發器;非觸發性約束將更「有效」。還有一整套單獨的問題與I4GL是否會識別CREATE TRIGGER的語法有關;您可能需要將該語句放在SQL CREATE TRIGGER ... END SQL塊中。 – 2012-08-11 21:17:00

+0

我不知道這個informix 4GL。在這裏,他們希望我創建一個觸發器,我嘗試通過select語句添加,但不知道。 – MJJ3 2012-08-13 17:05:09

+0

如果是課堂練習,那麼可能會有一些優點,但具體的約束條件如討論的那樣更好地處理。如果是生產代碼,那麼你需要向他們解釋他們的要求是不明智的,你可以讓他們看看這個和/或與我討論(請參閱我的個人資料的電子郵件地址)。 – 2012-08-13 18:09:43

回答

1

最簡單,最可靠的方法,以確保有表中沒有重複的數據不使用觸發器可言,但使用UNIQUE或PRIMARY KEY約束:

CREATE TABLE test1 
(
    code INTEGER NOT NULL PRIMARY KEY, 
    sname VARCHAR(32) NOT NULL UNIQUE 
); 

四個約束(二NOT NULL ,一個PRIMARY KEY,一個UNIQUE)自動確保沒有重複的記錄被插入到表中。

如果您選擇添加觸發器,它將複製由這些約束完成的工作。

至於如何做到這一點,您需要創建一個從觸發器語句中調用的存儲過程。它將被賦予新的代碼和新名稱,並執行SELECT以查看是否有匹配的記錄發生,如果有,則會引發異常,如果不匹配則不會引發異常。

CREATE PROCEDURE trig_insert_test1(ncode INTEGER, nname VARCHAR(32)) 
    DEFINE ocode INTEGER; 
    FOREACH SELECT code INTO ocode 
       FROM test1 
      WHERE code = ncode OR sname = nname 
     RAISE EXCEPTION -271, -100, "Value to be inserted already exists in table test1"; 
    END FOREACH; 
END PROCEDURE 

然後你使用:

CREATE TRIGGER ins_test1 INSERT ON test1 
    REFERENCING NEW AS NEW 
    FOR EACH ROW (EXECUTE PROCEDURE ins_trig_test1(new.code, new.sname)) 

在Informix的4GL,您可以創建包含這些語句中的字符串,然後準備和執行(而且免費)它們,或者您可以使用SQL塊:

SQL 
    CREATE TRIGGER ins_test1 INSERT ON test1 
     REFERENCING NEW AS NEW 
     FOR EACH ROW (EXECUTE PROCEDURE ins_trig_test1(new.code, new.sname)) 
END SQL 

但是,正如我在一開始所說的那樣,使用觸發器並不是最好的方法;根據表定義,它是多餘的。

我沒有運行過服務器的任何SQL或SPL;你需要檢查分號是否在SPL的正確位置,因爲SPL很挑剔。

您可以在Informix 11.70 Information Centre中找到SQL和SPL語句的語法。

+0

然後,你需要解釋一下你的設置。您的數據庫服務器是SE或IDS(或者,不太可能,OnLine或XPS)。它可能在同一臺機器上。你使用的是哪個版本的I4GL? (運行'i4gl -V'來找出。)如果您沒有對服務器進行任何管理,那麼您可能正在運行SE。您可以運行'$ INFORMIXDIR/lib/sqlexec -V'來確認並打印版本。如果你沒有'sqlexec'程序,你沒有SE;那麼應該有一個'$ INFORMIXDIR/bin/oninit'(或者可能是'$ INFORMIXDIR/bin/tbinit');你可以用'-V'標誌運行它來獲取版本。 – 2012-08-14 13:55:27

+0

SE 7.25在哪個O/S上運行?哪個版本的I4GL? – 2012-08-14 14:51:27

+0

不;我無法進一步幫助你,因爲你沒有看到正在崩潰的程序。它需要簡短而又甜美和完整。你不應該能夠讓程序崩潰(如'dump core');你可能會因爲出錯而停止。但是由於我看不到你有什麼代碼,所以沒有機會幫助你解決問題。要添加代碼,請編輯該問題。 – 2012-08-15 14:56:25