Loading...
MySQL 9.5 Reference Manual 9.5의 15.1.15 CREATE EVENT Statement의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
1CREATE 2 [DEFINER = user] 3 EVENT 4 [IF NOT EXISTS] 5 event_name 6 ON SCHEDULE schedule 7 [ON COMPLETION [NOT] PRESERVE] 8 [ENABLE | DISABLE | DISABLE ON {REPLICA | SLAVE}] 9 [COMMENT 'string'] 10 DO event_body 11 12schedule: { 13 AT timestamp [+ INTERVAL interval] ... 14 | EVERY interval 15 [STARTS timestamp [+ INTERVAL interval] ...] 16 [ENDS timestamp [+ INTERVAL interval] ...] 17} 18 19interval: 20 quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | 21 WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE | 22 DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
이 statement는 새로운 event를 생성하고 일정에 따라 실행되도록 예약합니다. Event Scheduler가 활성화되어 있지 않으면 event는 실행되지 않습니다. Event Scheduler 상태를 확인하고 필요한 경우 활성화하는 방법에 대한 정보는 Section 27.5.2, “Event Scheduler Configuration”을 참조하십시오.
CREATE EVENT는 event가 생성될 스키마에 대한 EVENT 권한이 필요합니다. DEFINER 절이 존재하는 경우 필요한 권한은 Section 27.8, “Stored Object Access Control”에서 설명하는 대로 user 값에 따라 달라집니다.
유효한 CREATE EVENT statement에 대한 최소 요구 사항은 다음과 같습니다:
CREATE EVENT 키워드와, 데이터베이스 스키마 내에서 event를 고유하게 식별하는 event 이름.
event가 언제, 얼마나 자주 실행되는지 결정하는 ON SCHEDULE 절.
event가 실행할 SQL statement를 포함하는 DO 절.
다음은 최소한의 CREATE EVENT statement 예입니다:
1CREATE EVENT myevent 2 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR 3 DO 4 UPDATE myschema.mytable SET mycol = mycol + 1;
이전 statement는 myevent라는 이름의 event를 생성합니다. 이 event는 생성 후 1시간이 지난 시점에 한 번만 실행되며, myschema.mytable 테이블의 mycol 컬럼 값을 1씩 증가시키는 SQL statement를 실행합니다.
_event_name_은 최대 길이가 64자인 유효한 MySQL 식별자여야 합니다. Event 이름은 대소문자를 구분하지 않으므로, 동일한 스키마 내에 myevent와 MyEvent라는 두 event를 둘 다 가질 수는 없습니다. 일반적으로 event 이름을 위한 규칙은 저장 루틴 이름에 대한 규칙과 동일합니다. Section 11.2, “Schema Object Names”를 참조하십시오.
Event는 스키마에 연관됩니다. _event_name_의 일부로 스키마가 명시되지 않으면 기본(현재) 스키마가 가정됩니다. 특정 스키마에 event를 생성하려면, schema_name.event_name 구문을 사용하여 스키마로 event 이름을 한정하십시오.
DEFINER 절은 event 실행 시 권한을 검사할 때 사용할 MySQL 계정을 지정합니다. DEFINER 절이 존재하는 경우 user 값은 'user_name'@'host_name', CURRENT_USER, 또는 CURRENT_USER()로 지정되는 MySQL 계정이어야 합니다. 허용되는 user 값은 Section 27.8, “Stored Object Access Control”에서 논의하는, 사용자가 가진 권한에 따라 달라집니다. Event 보안에 대한 추가 정보도 해당 section을 참조하십시오.
DEFINER 절이 생략되면 기본 definer는 CREATE EVENT statement를 실행한 사용자입니다. 이는 DEFINER = CURRENT_USER를 명시적으로 지정하는 것과 같습니다.
Event body 안에서 CURRENT_USER 함수는 event 실행 시 권한을 검사하는 데 사용되는 계정, 즉 DEFINER 사용자를 반환합니다. Event 내에서의 user 감사(auditing)에 대한 정보는 Section 8.2.23, “SQL-Based Account Activity Auditing”을 참조하십시오.
IF NOT EXISTS는 CREATE EVENT에 대해 CREATE TABLE에서와 동일한 의미를 갖습니다. 동일한 스키마에 _event_name_이라는 이름의 event가 이미 존재하면, 아무 작업도 수행되지 않고 오류도 발생하지 않습니다. (그러나 이러한 경우 경고는 생성됩니다.)
ON SCHEDULE 절은 event에 대해 정의된 _event_body_가 언제, 얼마나 자주, 그리고 얼마나 오래 반복되는지를 결정합니다. 이 절은 다음 두 가지 형태 중 하나를 사용합니다:
AT timestamp는 일회성 event에 사용됩니다. 이 절은 event가 _timestamp_로 지정된 날짜와 시간에 단 한 번만 실행됨을 지정합니다. _timestamp_에는 날짜와 시간이 모두 포함되어야 하며, 또는 datetime 값으로 평가되는 식이어야 합니다. 이를 위해 DATETIME 타입 또는 TIMESTAMP 타입의 값을 사용할 수 있습니다. 날짜가 과거인 경우, 다음과 같이 경고가 발생합니다:1mysql> SELECT NOW(); 2+---------------------+ 3| NOW() | 4+---------------------+ 5| 2006-02-10 23:59:01 | 6+---------------------+ 71 row in set (0.04 sec) 8 9mysql> CREATE EVENT e_totals 10 -> ON SCHEDULE AT '2006-02-10 23:59:00' 11 -> DO INSERT INTO test.totals VALUES (NOW()); 12Query OK, 0 rows affected, 1 warning (0.00 sec) 13 14mysql> SHOW WARNINGS\G 15*************************** 1. row *************************** 16 Level: Note 17 Code: 1588 18Message: Event execution time is in the past and ON COMPLETION NOT 19 PRESERVE is set. The event was dropped immediately after 20 creation.
자체가 어떤 이유로든 유효하지 않은 CREATE EVENT statement는 오류와 함께 실패합니다.
CURRENT_TIMESTAMP를 사용하여 현재 날짜와 시간을 지정할 수 있습니다. 이런 경우 event는 생성되자마자 바로 동작합니다.
현재 날짜와 시간 기준으로 미래의 어느 시점에 발생하는 event를 생성하려면(예: “지금으로부터 3주 후” 같은 표현), 선택적 절 + INTERVAL interval을 사용할 수 있습니다. interval 부분은 수량과 시간 단위의 두 부분으로 구성되며, Temporal Intervals에 설명된 구문 규칙을 따릅니다. 단, event를 정의할 때는 마이크로초를 포함하는 어떤 단위 키워드도 사용할 수 없습니다. 일부 interval 타입에서는 복합 시간 단위를 사용할 수 있습니다. 예를 들어, “2분 10초”는 + INTERVAL '2:10' MINUTE_SECOND로 표현할 수 있습니다.
Interval을 결합해서 사용할 수도 있습니다. 예를 들어, AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY는 “지금으로부터 3주 2일 후”와 동일합니다. 이러한 절의 각 부분은 + INTERVAL로 시작해야 합니다.
EVERY 절을 사용합니다. EVERY 키워드 뒤에는 앞의 AT 키워드에 대한 설명에서와 같이 _interval_이 옵니다. (EVERY에서는 + INTERVAL을 사용하지 않습니다.) 예를 들어 EVERY 6 WEEK는 “6주마다”를 의미합니다.EVERY 절에서는 + INTERVAL 절을 사용할 수 없지만, + INTERVAL에서 허용되는 동일한 복합 시간 단위를 사용할 수 있습니다.
EVERY 절에는 선택적인 STARTS 절을 포함할 수 있습니다. STARTS 뒤에는 반복이 시작되어야 하는 시점을 나타내는 timestamp 값이 오며, “지금으로부터 얼마 후”인지 지정하기 위해 + INTERVAL interval을 사용할 수도 있습니다. 예를 들어, EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK는 “지금으로부터 1주일 후부터 시작하여 3개월마다”를 의미합니다. 비슷하게, “지금으로부터 6시간 15분 후부터 시작하여 2주마다”는 EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE로 표현할 수 있습니다. STARTS를 지정하지 않는 것은 STARTS CURRENT_TIMESTAMP를 사용하는 것과 동일합니다. 즉, event가 생성되자마자 지정된 작업이 반복되기 시작합니다.
EVERY 절에는 선택적인 ENDS 절을 포함할 수 있습니다. ENDS 키워드 뒤에는 MySQL이 event 반복을 언제 중지해야 하는지 알려주는 timestamp 값이 옵니다. ENDS와 함께 + INTERVAL interval을 사용할 수도 있습니다. 예를 들어, EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK는 “지금으로부터 30분 후부터 시작하여 12시간마다 실행하고, 지금으로부터 4주 후에 종료”와 동일합니다. ENDS를 사용하지 않으면 event는 무기한 계속 실행됩니다.
ENDS는 STARTS와 동일한 복합 시간 단위 구문을 지원합니다.
EVERY 절에서는 STARTS, ENDS, 둘 다, 또는 둘 다 사용하지 않을 수도 있습니다.
반복되는 event가 자신의 스케줄링 interval 내에 종료되지 않으면, 그 결과 하나의 event에 대해 여러 인스턴스가 동시에 실행될 수 있습니다. 이것이 바람직하지 않다면, 동시에 실행되는 인스턴스를 방지하기 위한 장치를 마련해야 합니다. 예를 들어, GET_LOCK() 함수나 row 또는 테이블 락을 사용할 수 있습니다.
ON SCHEDULE 절은 포함된 timestamp 또는 interval 값을 얻기 위해 MySQL 내장 함수와 사용자 변수를 사용하는 식을 사용할 수 있습니다. 이러한 식에서 저장 함수나 로더블 함수는 사용할 수 없으며, 테이블 참조도 사용할 수 없습니다. 그러나 SELECT FROM DUAL은 사용할 수 있습니다. 이는 CREATE EVENT와 ALTER EVENT statement 모두에 대해 마찬가지입니다. 이러한 경우 저장 함수, 로더블 함수, 테이블에 대한 참조는 명시적으로 허용되지 않으며, 오류와 함께 실패합니다(Bug #22830 참조).
ON SCHEDULE 절의 시간은 현재 세션의 time_zone 값으로 해석됩니다. 이것이 event 타임존, 즉 event 스케줄링에 사용되며 event가 실행될 때 event 내부에서 적용되는 타임존이 됩니다. 이 시간은 UTC로 변환되어 event 타임존과 함께 내부적으로 저장됩니다. 이를 통해 이후 서버 타임존 변경이나 일광 절약 시간제(DST) 효과에 관계없이 event 실행이 정의된 대로 진행될 수 있습니다. Event 시간 표현에 대한 추가 정보는 Section 27.5.4, “Event Metadata”를 참조하십시오. 또한 Section 15.7.7.20, “SHOW EVENTS Statement”와 Section 28.3.14, “The INFORMATION_SCHEMA EVENTS Table”도 참조하십시오.
일반적으로 event가 만료되면 즉시 drop됩니다. ON COMPLETION PRESERVE를 지정하여 이 동작을 재정의할 수 있습니다. ON COMPLETION NOT PRESERVE를 사용하는 것은 기본 비영속(nonpersistent) 동작을 명시적으로 나타낼 뿐입니다.
Event를 생성하되 활성 상태가 되지 않도록 하려면 DISABLE 키워드를 사용할 수 있습니다. 또는 기본 상태(활성)를 명시하기 위해 ENABLE을 사용할 수 있습니다. 이는 ALTER EVENT와 함께 사용할 때 가장 유용합니다( Section 15.1.3, “ALTER EVENT Statement” 참조).
ENABLE 또는 DISABLE 대신 세 번째 값이 나타날 수도 있습니다. DISABLE ON REPLICA는 레플리카에서의 event 상태를 설정하는 데 사용되며, 해당 event가 복제 소스 서버에서 생성되어 레플리카로 복제되었지만 레플리카에서는 실행되지 않음을 나타냅니다. Section 19.5.1.16, “Replication of Invoked Features”를 참조하십시오.
DISABLE ON REPLICA는 DISABLE ON SLAVE를 대체합니다. DISABLE ON SLAVE는 지원 중단(deprecated) 상태이며, 향후 MySQL 버전에서 제거될 수 있습니다.
COMMENT 절을 사용하여 event에 코멘트를 제공할 수 있습니다. _comment_는 event를 설명하기 위해 사용할 수 있는 최대 64자의 임의 문자열일 수 있습니다. 코멘트 텍스트는 문자열 리터럴이므로 따옴표로 둘러싸야 합니다.
DO 절은 event에 의해 수행되는 동작을 지정하며, 하나의 SQL statement로 구성됩니다. 저장 루틴에서 사용할 수 있는 거의 모든 유효한 MySQL statement는 스케줄된 event의 action statement로 사용할 수 있습니다( Section 27.10, “Restrictions on Stored Programs” 참조). 예를 들어, 다음 event e_hourly는 site_activity 스키마의 일부인 sessions 테이블의 모든 row를 매 시간마다 한 번씩 삭제합니다:
1CREATE EVENT e_hourly 2 ON SCHEDULE 3 EVERY 1 HOUR 4 COMMENT 'Clears out sessions table each hour.' 5 DO 6 DELETE FROM site_activity.sessions;
MySQL은 event가 생성되거나 변경될 때의 sql_mode 시스템 변수 설정을 저장하며, event가 실행을 시작할 때의 서버 SQL mode와 상관없이 항상 이 설정을 적용하여 event를 실행합니다.
DO 절에 ALTER EVENT statement를 포함하는 CREATE EVENT statement는 성공하는 것처럼 보입니다. 그러나 서버가 결과로 생성된 스케줄된 event를 실행하려고 시도할 때, 실행은 오류와 함께 실패합니다.
참고
SELECT나 SHOW와 같이 결과 집합만 반환하는 statement는 event에서 사용해도 아무 효과가 없습니다. 이들의 출력은 MySQL Monitor로 전송되지도 않고 어디에도 저장되지도 않습니다. 그러나 결과를 저장하는 SELECT ... INTO나 INSERT INTO ... SELECT와 같은 statement는 사용할 수 있습니다. (이에 대한 예는 이 section의 다음 예제를 참조하십시오.)
Event가 속한 스키마는 DO 절에서 테이블 참조에 대한 기본 스키마입니다. 다른 스키마의 테이블에 대한 참조는 적절한 스키마 이름으로 한정해야 합니다.
저장 루틴과 마찬가지로, BEGIN 및 END 키워드를 사용하여 DO 절에서 복합 구문(compound-statement) 구문을 사용할 수 있습니다. 다음 예를 참조하십시오:
1delimiter | 2 3CREATE EVENT e_daily 4 ON SCHEDULE 5 EVERY 1 DAY 6 COMMENT 'Saves total number of sessions then clears the table each day' 7 DO 8 BEGIN 9 INSERT INTO site_activity.totals (time, total) 10 SELECT CURRENT_TIMESTAMP, COUNT(*) 11 FROM site_activity.sessions; 12 DELETE FROM site_activity.sessions; 13 END | 14 15delimiter ;
이 예는 statement delimiter를 변경하기 위해 delimiter 명령을 사용합니다. Section 27.1, “Defining Stored Programs”을 참조하십시오.
저장 루틴에서 사용되는 것과 같은 더 복잡한 복합 구문도 event에서 가능합니다. 다음 예는 로컬 변수, 오류 핸들러, 실행 흐름 제어 구문을 사용합니다:
1delimiter | 2 3CREATE EVENT e 4 ON SCHEDULE 5 EVERY 5 SECOND 6 DO 7 BEGIN 8 DECLARE v INTEGER; 9 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; 10 11 SET v = 0; 12 13 WHILE v < 5 DO 14 INSERT INTO t1 VALUES (0); 15 UPDATE t2 SET s1 = s1 + 1; 16 SET v = v + 1; 17 END WHILE; 18 END | 19 20delimiter ;
Event에 파라미터를 직접 전달하거나 event로부터 파라미터를 직접 반환하는 방법은 없습니다. 그러나 event 안에서 파라미터를 가진 저장 루틴을 호출하는 것은 가능합니다:
1CREATE EVENT e_call_myproc 2 ON SCHEDULE 3 AT CURRENT_TIMESTAMP + INTERVAL 1 DAY 4 DO CALL myproc(5, 27);
MySQL 9.5에서 CREATE EVENT statement는 prepare할 수 있지만, statement 텍스트에는 플레이스홀더(?)가 포함되어서는 안 됩니다. 이 제한을 우회하는 한 가지 방법은 statement 텍스트를 조합한 후 저장 프로시저 내에서 이를 prepare 및 execute하는 것입니다. CREATE EVENT statement의 가변 부분은 파라미터로 저장 프로시저에 전달할 수 있습니다. 다음 예에서는 이미 다음과 같이 생성된 데이터베이스 d의 테이블 t가 존재한다고 가정합니다:
1USE d; 2 3CREATE TABLE t ( 4 c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 5 c2 VARCHAR(20), 6 c3 INT 7);
우리는 생성 시점에 결정된 interval마다 이 테이블에 row를 insert하는 event를 생성하고자 합니다. 이는 다음 statement로 정의된 event와 유사합니다:
1CREATE EVENT e 2 ON SCHEDULE EVERY interval SECOND 3 STARTS CURRENT_TIMESTAMP + INTERVAL 10 SECOND 4 ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE 5 ON COMPLETION PRESERVE 6 DO 7 INSERT INTO d.t1 VALUES ROW(NULL, NOW(), FLOOR(RAND()*100));
_interval_에 대한 플레이스홀더로 ?를 사용할 수는 없지만, 다음과 같은 저장 프로시저에 파라미터 값을 전달할 수는 있습니다:
1delimiter | 2 3CREATE PROCEDURE sp(n INT) 4BEGIN 5 SET @s1 = "CREATE EVENT e ON SCHEDULE EVERY "; 6 SET @s2 = " SECOND 7 STARTS CURRENT_TIMESTAMP + INTERVAL 10 SECOND 8 ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE 9 ON COMPLETION PRESERVE 10 DO 11 INSERT INTO d.t VALUES ROW(NULL, NOW(), FLOOR(RAND()*100))"; 12 13 SET @s = CONCAT(@s1, n, @s2); 14 PREPARE ps FROM @s; 15 EXECUTE ps; 16 DEALLOCATE PREPARE ps; 17END | 18 19delimiter ;
1mysql> TABLE t; 2Empty set (0.00 sec) 3 4mysql> CALL sp(5); 5Query OK, 0 rows affected (0.01 sec) 6 7# Wait 2 minutes... 8 9mysql> TABLE t; 10+----+---------------------+------+ 11| c1 | c2 | c3 | 12+----+---------------------+------+ 13| 1 | 2024-06-12 15:53:36 | 41 | 14| 2 | 2024-06-12 15:53:41 | 84 | 15| 3 | 2024-06-12 15:53:46 | 71 | 16| 4 | 2024-06-12 15:53:51 | 78 | 17| 5 | 2024-06-12 15:53:56 | 53 | 18| 6 | 2024-06-12 15:54:01 | 6 | 19| 7 | 2024-06-12 15:54:06 | 48 | 20| 8 | 2024-06-12 15:54:11 | 98 | 21| 9 | 2024-06-12 15:54:16 | 22 | 22| 10 | 2024-06-12 15:54:21 | 88 | 23| 11 | 2024-06-12 15:54:26 | 53 | 24| 12 | 2024-06-12 15:54:31 | 75 | 25| 13 | 2024-06-12 15:54:36 | 93 | 26| 14 | 2024-06-12 15:54:41 | 13 | 27| 15 | 2024-06-12 15:54:46 | 62 | 28| 16 | 2024-06-12 15:54:51 | 47 | 29| 17 | 2024-06-12 15:54:56 | 22 | 30| 18 | 2024-06-12 15:55:01 | 47 | 31| 19 | 2024-06-12 15:55:06 | 43 | 32| 20 | 2024-06-12 15:55:11 | 50 | 33| 21 | 2024-06-12 15:55:16 | 98 | 34| 22 | 2024-06-12 15:55:21 | 15 | 35| 23 | 2024-06-12 15:55:26 | 56 | 36+----+---------------------+------+ 3723 rows in set (0.00 sec)
위와 같이 argument 값 5로 sp를 호출하고 event e가 실행을 완료할 때까지 2분을 기다린 후, 테이블 t가 5초마다 업데이트되었음을 확인할 수 있습니다. e가 ON COMPLETION PRESERVE로 생성되었으므로, Information Schema EVENTS 테이블에서 이를 확인하고 기대한 대로 생성되었는지 검증할 수 있습니다:
1mysql> SELECT EVENT_NAME, EVENT_SCHEMA, EVENT_DEFINITION, EVENT_TYPE 2 > FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='e'\G 3*************************** 1. row *************************** 4 EVENT_NAME: e 5 EVENT_SCHEMA: d 6EVENT_DEFINITION: INSERT INTO d.t VALUES ROW(NULL, NOW(), FLOOR(RAND()*100)) 7 EVENT_TYPE: RECURRING 81 row in set (0.00 sec)
Event의 definer가 글로벌 시스템 변수를 설정하기에 충분한 권한을 가지고 있는 경우( Section 7.1.9.1, “System Variable Privileges” 참조), event는 글로벌 변수를 읽고 쓸 수 있습니다. 이러한 권한을 부여하는 것은 악용 가능성이 있으므로, 이를 수행할 때는 극도로 주의해야 합니다.
일반적으로 저장 루틴에서 유효한 statement는 event에 의해 실행되는 action statement로 사용할 수 있습니다. 저장 루틴 내에서 허용되는 statement에 대한 자세한 정보는 Section 27.2.1, “Stored Routine Syntax”를 참조하십시오. 저장 루틴의 일부로 event를 생성하거나, 다른 event에 의해 event를 생성하는 것은 불가능합니다.
15.1.14 CREATE DATABASE Statement
15.1.16 CREATE FUNCTION Statement