質問

挿入されたレコードに対して次の操作を実行するトリガーが欲しい:

 # pseudocode
 if new.group_id is null
    set new.group_id = new.id
 else
    # don't touch it
 end

より明確に:3つの列を持つテーブルが1つあるとします: id 主キー、 group_id int、 value varchar。

そのような group_id で挿入すると:

INSERT INTO table(value, group_id) VALUES ('a', 10)

欲しいのは:

id | group_id | value
---+----------+------
 1 |       10 | a

しかし、 group_id を省略すると:

INSERT INTO table(value) VALUES ('b')

このレコードの id に自動的に設定される必要があります:

id | group_id | value
---+----------+------
 2 |        2 | b

トリガーで可能ですか? (挿入後にレコードを更新できることはわかっていますが、トリガーを使用する方が良いでしょう。)

役に立ちましたか?

解決

トリガーを使用しても、1つのステートメントでこれを行う方法はわかりません。

@Luckyが提案したトリガーソリューションは、MySQLでは次のようになります。

CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
  SET NEW.group_id = COALESCE(NEW.group_id, NEW.id);
END

ただし、問題があります。 BEFORE INSERT フェーズでは、自動生成された id 値はまだ生成されていません。したがって、 group_id がnullの場合、デフォルトは NEW.id であり、常に0です。

ただし、 AFTER INSERT フェーズ中にこのトリガーを起動するように変更すると、生成された NEW.id の値にアクセスできるため、列を変更できません値。

MySQLは列の DEFAULT の式をサポートしていないため、テーブル定義でもこの動作を宣言できません。

唯一の解決策は、 INSERT を実行し、設定されていない場合はすぐに UPDATE を実行して group_id を変更することです。

INSERT INTO MyTable (group_id, value) VALUES (NULL, 'a');
UPDATE MyTable SET group_id = COALESCE(group_id, id) WHERE id = LAST_INSERT_ID();

他のヒント

ここで回答しています。受け入れられている回答ビルカーウィンは次のように述べています。

  

BEFORE INSERTフェーズでは、自動生成されたid値は   まだ生成されています。したがって、group_idがnullの場合、デフォルトはNEW.idになります。   常に0です。


私はそれに対する答えを持っています-OP(および来るべき訪問者)にとって、ここにいくつかのポイントがあります: トリガーが呼び出される場所からテーブルを更新することはできません。そのため、エラー1442 が表示されます:

Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

1。新しい行を更新する BEFORE INSERT ON トリガーを使用して、この方法で新しい行のすべてのフィールドを更新できます。これには、NEW演算子、つまり

からアクセスできます。
set NEW.group_id = NEW.id

2。挿入前にauto_increment値を取得

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='MyTable'

要約すると、 'dのトリガーSQLは次のようになります:

DELIMITER //
DROP TRIGGER IF EXISTS MyTrigger//
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
    IF new.group_id IS NULL
        set @auto_id := (SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES
                         WHERE TABLE_NAME='MyTable' AND TABLE_SCHEMA=DATABASE() ); 
        set NEW.group_id = @auto_id;
    ENF IF;
END;
//
DELIMITER ;

これは私のために動作します

DELIMITER $
CREATE TRIGGER `myTriggerNameHere`
BEFORE INSERT ON `table` FOR EACH ROW
BEGIN
    SET NEW.group_id = IF(NEW.group_id IS NULL, LAST_INSERT_ID()+1, NEW.group_id);
END;
$
DELIMITER ;

これはあなたに役立つと信じています

2つのテーブルがあります

test_b: a_id, value
test_c: a_id, value

そして、ここにテストbの挿入のトリガーがあります。 a_idがnullであるかどうかを確認し、nullである場合は0を挿入します

CREATE TRIGGER test_b AFTER INSERT ON test_b
  FOR EACH ROW 
    INSERT INTO test_c (a_id, value) VALUES (IFNULL(NEW.a_id, 0),NEW.value)

このトリガーは、あなたが要求したことを行うはずです。

   CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
          IF new.group_id IS NULL
            SET new.group_id = new.id
          END IF
      END;

MYSQLドキュメントの非常によく似た例からコピーされていますページ。

この状況では、トリガーは過剰に思えます。デフォルトを適用するだけです。

CREATE TABLE `test` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `value` varchar(100) NOT NULL,
    `group_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2'
)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top