문제

삽입된 레코드에 대해 다음 작업을 수행하는 트리거를 갖고 싶습니다.

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

훨씬 선명하게:세 개의 열이 있는 하나의 테이블이 있다고 가정해 보겠습니다. id 기본 키, group_id 정수, 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

트리거로 가능한가요?(삽입한 후 레코드를 업데이트할 수 있다는 것을 알고 있지만 트리거를 사용하는 것이 더 좋을 것입니다.)

도움이 되었습니까?

해결책

트리거를 사용하여 한 명령 에서이 작업을 수행하는 방법을 모릅니다.

@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();

다른 팁

허용된 답변에서와 같이 여기에 답변하고 있습니다. 빌 카윈 상태:

이전 삽입 단계에서는 자동 생성 된 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'

요약하면 '에 대한 트리거 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 ;

나는 이것이 당신에게 효과가 있다고 믿는다

나는 두 개의 테이블이 있습니다

test_b: a_id, value
test_c: a_id, value

그리고 여기 테스트 삽입에 대한 트리거가 있습니다. b. a_id가 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