programing

Mysql/MariaDB 트리거 문제 및 디버그

subpage 2023. 9. 6. 22:06
반응형

Mysql/MariaDB 트리거 문제 및 디버그

저는 현재 제 자신의 즐거움과 지식을 위한 토큰 리더(RFID) 서비스를 개발하고 있습니다.저는 영어보다 불어를 더 잘하니 사과 부탁드립니다.구글 번역은 내 친구지만..

제 프로젝트는 정말 간단합니다.

  • Wish에서 RFID 리더를 구입했습니다.
  • RFID 코드 판독을 수신하는 HTML 웹페이지
  • 내 테이블 t_rfids 코드에 SELECT를 선택하여 첨부된 사용자를 검색하는 Ajax Query

  • _users_id가 NULL INSERT t_accesslogs 항목이 아닌 경우.

테이블 구조는 다음과 같습니다.

CREATE TABLE test_punch.t_accesslogs (
  id_tokenaccesslog bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  punchtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  id_ref_user bigint(20) UNSIGNED NOT NULL,
  PRIMARY KEY (id_tokenaccesslog)
)
ENGINE = INNODB,
CHARACTER SET latin1,
COLLATE latin1_swedish_ci;

따라서 간단한 INSERT INTOT_accesslogs (id_ref_user) Values (3)를 만들어 CURN_TIME stamp에 대한 입력을 받았습니다.

모든 것이 잘 작동하지만 접속 로그를 날짜, time_start, time_end로 타임카드 항목에 최적화하려고 합니다.테이블 구조:

CREATE TABLE test_punch.t_timecards (
  id_timecard bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  id_ref_user bigint(20) UNSIGNED NOT NULL,
  day_date date NOT NULL,
  time_begin time NOT NULL,
  time_end time DEFAULT NULL,
  PRIMARY KEY (id_timecard)
)
ENGINE = INNODB,
CHARACTER SET latin1,
COLLATE latin1_swedish_ci;

저는 외부 코드를 사용하지 않고 이 테이블을 채우는 최선의 방법을 찾으려고 노력합니다. 그래서 트리거(Trigger)트리거 코드는 다음과 같습니다.

CREATE 
DEFINER = 'root'@'localhost' 
TRIGGER test_punch.add_timecard_entry
    AFTER INSERT
    ON test_punch.t_accesslogs
    FOR EACH ROW
    BEGIN
      DECLARE bint_IdTimeCard BIGINT; 
      DECLARE dt_Punch DATE;
      DECLARE time_Start TIME;
      DECLARE time_End TIME;

      SELECT  t_timecards.id_timecard INTO bint_IdTimeCard 
      FROM t_timecards
      WHERE t_timecards.id_ref_user = NEW.id_ref_user 
        AND  day_date = CAST(NEW.punchtime as DATE)
        AND  time_begin IS NOT NULL
        AND  time_end IS NULL;

      IF (bint_IdTimeCard IS NOT NULL) THEN
        UPDATE t_timecards 
        SET t_timecards.time_end = CAST(NEW.punchtime AS TIME) 
        WHERE t_timecards.id_timecard=bint_IdTimeCard
          AND t_timecards.id_ref_user=NEW.id_ref_user;
      ELSE
        INSERT INTO t_timecards (id_ref_user,day_date,time_begin) 
        VALUES (NEW.id_ref_user,
                CAST(NEW.punchtime AS DATE),
                CAST(NEW.punchtime AS TIME));
      END IF;
END

SELECT 값이 Null일 경우 반환되는 값이 첫 번째 확실하지 않습니다.진짜 NULL입니까 아니면 비어 있습니까?앞서 말한 것처럼 dbForge Studio를 사용해도 디버깅이 어렵습니다(MySQL 트리거 디버깅 참조).

실제로 코드 동작은 IF 문을 올바르게 처리하지 못하는 것처럼 보였습니다.제가 뭘 잘못하고 있는지 아시겠어요?

어떤 도움이라도 주시면 감사하겠습니다.

감사해요.

마틴

할 수 있다면 하지 마.이런 일에는 트리거를 사용하지 마십시오.트리거를 사용하는 이유는 참조 무결성을 유지하기 위해서입니다.필요하지 않다면, 그것들도 사용하지 않는 것이 좋습니다.대신 DRI에 의존합니다.

삽입할 때 이와 같은 방식으로 데이터를 조정할 필요가 없습니다.이렇게 하면 응용프로그램이 더 복잡해지고 신뢰성이 떨어지게 됩니다.

그 대신 전망을 추천합니다.테이블을 사용할 때 테이블을 나타내는 보기를 작성합니다.당신의 목적에 맞는지 확인해 보세요.

보기의 성능이 좋지 않을 경우 다른 표현을 유지하는 데 도움이 될 수 있습니다.그렇다면 저장 프로시저를 사용하여 테이블에 삽입하는 수준 이상으로 원하는 작업을 수행하고 응용 프로그램에서 저장 프로시저를 사용하도록 요구합니다.도출된 정보를 보관하기 위해 두 번째 표를 사용하는 것이 편리할 수 있습니다.

댓글 달아주셔서 감사합니다.저장 프로시저 대신 트리거를 사용하는 것이 더 쉽다는 것을 알았지만 저장 프로시저를 시도해 보겠습니다.사실은 제 테이블 t_access logs가 제 "진실" 테이블이 되고 남는다는 것입니다.제 접근 방식에서는 t_timecards 테이블에서만 이 테이블에서 항목을 추가/제거할 계획이 없었습니다.아마도 제 논리는 검토해야 할 것 같습니다.

저는 보기를 작성하려고 하는데, 사람이 실수로 두 번 "밀었다"고 하는 것처럼 예외를 없애는 것을 제외하고는 잘 작동하고 있습니다.

여기 내 보기 코드:

SELECT
    `t_accesslogs`.`id_ref_user` AS `id_user`,
    `t_accesslogs`.`dt_scan`     AS `dt_scan`,
    MIN(`t_accesslogs`.`dt_scan`) AS `dt_scan_min`,
    MAX(`t_accesslogs`.`dt_scan`) AS `dt_scan_max`
FROM `t_accesslogs`
GROUP BY CAST(`t_accesslogs`.`dt_scan` AS DATE)

말씀드린 것처럼 그건 일이지만 시작과 종료 타임스탬프를 자동화하려고 노력합니다.보관 절차를 해보고 알려드리겠습니다.

감사해요.

편집:

흠, 이상해요.디버깅에 관한 기사를 사용해 보니 문제는 SELECT였습니다.WHERE 조건을 다음과 같이 변경했습니다.

WHERE t_timecards.id_ref_user = NEW.id_ref_user 
  AND  day_date = CAST(NEW.punchtime AS DATE)
  AND  time_begin IS NOT NULL 
  AND time_end IS NULL;

타고

WHERE t_timecards.id_ref_user = NEW.id_ref_user 
  AND  day_date = CAST(NEW.punchtime AS DATE)
  AND  (time_begin IS NOT NULL AND time_end IS NULL);

행동을 고칠 수 있을 겁니다더 읽어봐야 할 것 같아요.

도와주셔서 감사하며 트리거를 저장 프로시저로 전환하겠습니다.맞아요, 디버그하기 쉽죠.

언급URL : https://stackoverflow.com/questions/53120788/mysql-mariadb-trigger-issue-and-debug

반응형