2017-03-21 5 views
1

ユーザー評価を格納するテーブルpledgeRatingがあります。すべての挿入時に、私は以下のトリガがpledgeTemplateテーブルにratingsCountrating列を更新するために実行します。完全を期すために更新クエリがトリガーからのものであるかどうかを検出します。

CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeRating_AFTER_INSERT` AFTER INSERT ON `pledgeRating` FOR EACH ROW 
BEGIN 
    UPDATE `pledgeTemplate` 
     SET `rating` = ((`rating` * `ratingsCount`) + NEW.rating)/(`ratingsCount` + 1), 
      `ratingsCount` = `ratingsCount` + 1 
     WHERE `id` = NEW.pledgeTemplateID; 
END 

私はpledgeTemplateテーブルに直接ratingsCountrating列を更新からすべてのMySQLユーザーを防止したいです。これらの2つの列をトリガーからのみ更新する必要があります。

CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeTemplate_BEFORE_UPDATE` BEFORE UPDATE ON `pledgeTemplate` FOR EACH ROW 
BEGIN 
    IF (OLD.ratingsCount != NEW.ratingsCount OR OLD.rating != NEW.rating) AND {{Update query is not from the trigger}} THEN 
     SIGNAL sqlstate '45000' SET message_text = 'Error: Only trigger can modify ratingsCount or rating columns'; 
    END IF; 
END 
:私は更新クエリを実行しているユーザーを検証するために pledgeTemplateテーブルに新しいトリガを作成しましたが、私はその更新がトリガーからかそうでないかを検出する方法を見つけることができないことを実現するために

最初のトリガからフラグを渡すことができるので、2番目のトリガでトリガが検出されたかどうかを検出できますか?私はCURRENT_USERオブジェクトとUSER()の機能を調べましたが、これは参考になると思いました。ただし、CURRENT_USERは常にDEFINERに設定され、USER()は常に初期クエリを実行するユーザーを返します。

したがって、pledgeTemplateテーブルの更新クエリがトリガーまたは「直接」更新から実行されるかどうかを検出する方法はありますか。 Hello_

+1

私は考えていませんが、あなたのユーザのためにそれぞれのテーブルのUPDATEパーミッションを削除することができます – Mihai

+0

それでも、私のユーザは 'pledgeTemplate'テーブルを更新する必要があります。 UPDATE権限を削除すると、すべての更新を停止します。私はちょうどそれらの2つの列がトリガー以外から更新されないように保護したい。 – Guferos

答えて

0

は、最初に私はコメントで私の考えを説明するために始めたが、それはあまりにも長くはないだけでなく書式設定になっているようです。あなたはそれで大丈夫ですが、私はそれを共有するのであれば、これは単なるアイデアですが、私は知りません。

  1. ALTER TABLE pledgeTemplate ADD COLUMN isTriggerUpdate BIT NULL DEFAULT 0;を - 私たちは私たちがどうかを判断するためのフラグとして使用することができ、テーブルに列を追加します更新がトリガまたはユーザー

2.

CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeRating_AFTER_INSERT` 
AFTER INSERT ON `pledgeRating` FOR EACH ROW 
BEGIN 
    UPDATE `pledgeTemplate` 
     SET `rating` = ((`rating` * `ratingsCount`) + NEW.rating)/(`ratingsCount` + 1), 
      `ratingsCount` = `ratingsCount` + 1, 
      `isTriggerUpdate ` = 1 
     WHERE `id` = NEW.pledgeTemplateID; 
END 

変更真

にフラグ列を設定するには、あなたのトリガ pledgeRating_AFTER_INSERTのコードから来ています

3.

CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeTemplate_BEFORE_UPDATE` 
BEFORE UPDATE ON `pledgeTemplate` FOR EACH ROW 
BEGIN 
    IF (OLD.ratingsCount != NEW.ratingsCount OR OLD.rating != NEW.rating) 
     AND NEW.isTriggerUpdate != 1 THEN 
     SIGNAL sqlstate '45000' SET message_text = 'Error: Only trigger can modify ratingsCount or rating columns'; 
    END IF; 
END 

今、あなたは、このようなpledgeTemplate_BEFORE_UPDATEで不足している状態を持つことができます。

私はこれがロジックとして機能すると思いますが、問題はこれを実装する最も効率的なロジックですか。このロジックでは、isTriggerUpdateの列をフロントエンドに公開することはできません。単純にtrueに設定すると、このロジックをバイパスします。

Good Luck!

関連する問題