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
'programing' 카테고리의 다른 글
CSS로 이미지를 그레이아웃하시겠습니까? (0) | 2023.09.11 |
---|---|
NSParameterAssert란? (0) | 2023.09.11 |
mariadb에서 버려진 연결 정리(mysql과 비교)? (0) | 2023.09.06 |
jquery detection 특정 클래스의 div가 DOM에 추가되었습니다. (0) | 2023.09.06 |
python에서 클래스의 모든 멤버 변수를 루핑 (0) | 2023.09.06 |