挿入されたレコードに対して次の操作を実行するトリガーが必要です。
# 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)