2017-10-31 4 views
2

トリガーがエラーなしで戻ってきます。しかし、私はそれをテストすると、エラーメッセージは返されず、テストデータはテーブルに格納されています..私がしたいものではありません。MySQLトリガーが完全に機能しない

は、基本的に(これは授業のためのものである)、Iはバルセロナ以外の場所がテーブルに挿入されているエラーメッセージを表示するトリガしたいです。

これは私の引き金です。私が言ったように、エラーは戻って来ないが、うまくいかない? LocationTriggerがnullの場合

DELIMITER $$ 

CREATE TRIGGER after_location_insert_finance 
AFTER INSERT ON Finance 
FOR EACH ROW 

BEGIN 
DECLARE LocationTrigger varchar(255); 
DECLARE msg varchar(255); 

SELECT Location INTO LocationTrigger 
FROM Finance 
WHERE Location != "Barcelona"; 

IF(LocationTrigger != "Barcelona") THEN 
SIGNAL SQLSTATE '45000' 
SET MESSAGE_TEXT = 'Not a valid location'; 
END IF; 

END$$ 
+0

はこれを修正する...大切トリTRUE、FALSEおよびNULLである: 'WHERE場所<> 'バルセロナ';'と 'IF(LocationTrigger <> 'バルセロナ') ' –

+0

@ Harshil:**'!= '**演算子を**' <> '**に置き換えると、その変更は動作を変更するとは思いません。 MySQLでは、これら2つの演算子は同義語であり、どちらも同じ演算を表します。 – spencer7593

答えて

0

IFで式がTRUEと評価されません。

WHERE節の条件を満たす行がない場合、LocationTriggerはNULLになります。

locationの列に値が挿入されていることを確認できない理由がわかりません。リテラル値'Barcelona'と比較するときに、なぜBossテーブルのクエリを実行しているのでしょうか。

AFTERトリガーではなく、BEFOREトリガーでこの種のチェックが必要なようです。

locationのNULL値を許可しますか?

locationに挿入できる唯一の値が'Barcelona'であり、NULL値を許可しない場合は、Bossテーブルのクエリを処理する必要はありません。ただ、比較...

BEGIN 
    IF NOT (NEW.location <=> 'Barcelona') THEN 
     SIGNAL ... 
    END IF; 
END 

たぶんトリガーの目標は、参照整合性制約強制することです(私たちは通常、むしろ手順を実行するよりも、FOREIGN KEY制約を宣言することで実現すると思います。)

、「有効」の場所はBoss表にlocation値のドメインによって定義されていると仮定すると

、その後、我々はNULL値を許可するつもりはないと仮定すると:

BEGIN 
    DECLARE ls_location VARCHAR(255) DEFAULT NULL; 
    -- check if the value being inserted exists in a lookup table 
    SELECT b.location INTO ls_location 
    FROM Boss b 
    WHERE b.location = NEW.location 
    LIMIT 1 
    ; 
    -- if we didn't find a match, ls_location will be NULL 
    IF ls_location IS NULL THEN 
     SIGNAL ... 
    END IF; 
END 

Bossに一致する行がない場合、ls_locationはNULLになります。

NULLとの比較が "not equals"の場合、TRUEまたはFALSEではなくNULLに評価されます。

ブール論理は、SQLが

SELECT 0  = 1  AS c0 
     , 0 <> 1  AS c1 
     , 0  = NULL AS c2 
     , 0 <> NULL AS c3 
     , NULL = NULL AS c4 
     , NULL <> NULL AS c5 
+0

私のトリガーはちょっと混乱します(私は 'boss'テーブルを参照しているものすべてを削除しました。すべてが 'finance'テーブルに関連するはずです)。はい、あなたの目標は、整合性制約を強制することです。このデータベースの私の完全性の制約は、その場所がバルセロナであることになります。したがって、挿入された場所がバルセロナ以外のものであれば、エラーメッセージを送信するトリガーを作成しようとしていました。 (このデータベースは本質的に8つのテーブルであり、上記のデータベースとは一連の作業があります。テーブルが全く正確に関係していない場合) –

+0

@GeorgeGilliland:BEFORE INSERTトリガーを実装します。挿入されている場所の値をリテラルと比較する** IF NOT(NEW.location <=> 'Barcelona')THEN' **は例外を発生させます。 '<=>'(宇宙船)演算子は、比較される式がNULLであってもTRUEまたはFALSEを返すnull安全比較です。 MySQLリファレンスマニュアルに記載されています。 'a <=> b'は' a = b OR(a IS NULLとb IS NULL) 'に相当する省略表現です。 – spencer7593

関連する問題