Creating a complex trigger in PHP MyAdmin.

huangapple go评论65阅读模式
英文:

Creating a complex trigger in PHP MyAdmin

问题

DELIMITER ;
DROP TRIGGER IF EXISTS `calculate_duration`;
DELIMITER $$
CREATE TRIGGER `calculate_duration`
AFTER INSERT
ON `events`
FOR EACH ROW
BEGIN
  IF NEW.clock_on IS NOT NULL AND NEW.clock_off IS NOT NULL THEN
    UPDATE events
      SET time_clocked = UNIX_TIMESTAMP(NEW.clock_off) - UNIX_TIMESTAMP(NEW.clock_on),
          clock_on = NULL,
          clock_off = NULL
      WHERE id = NEW.id;
  END IF;
  IF (
    DAYOFWEEK(CURRENT_DATE()) IN (1, 2, 3, 4)
    AND HOUR(NOW()) = 23
    AND NEW.clock_off IS NULL
  ) THEN
    INSERT INTO events (clock_on, clock_off, time_clocked)
      VALUES (CURRENT_DATE(), '16:15', NEW.time_clocked);
  END IF;
  IF (
    DAYOFWEEK(CURRENT_DATE()) = 5
    AND HOUR(NOW()) = 23
    AND NEW.clock_off IS NULL
  ) THEN
    INSERT INTO events (clock_on, clock_off, time_clocked)
      VALUES (CURRENT_DATE(), '12:15', NEW.time_clocked);
  END IF;
END$$
DELIMITER;
英文:

Hi I'm a total noob in SQL.

I'm trying to write a trigger to insert into PHP MyAdmin that accomplished the following:

  1. Table = 'events', Fields = 'clock_on' (datetime field), 'clock_off' (datetime field) and 'time_clocked' (tinyint(11) field).

  2. When 'clock_on' and 'clock_off' are not NULL then calculate the time elapsed and insert this time into the 'time_clocked' field then reset the values in 'clock_on' and 'clock_off' to NULL.

  3. When 'clock_on' and 'clock_off' are not NULL then calculate the time elapsed and ADD this to the existing value in 'time_clocked' then reset the values in 'clock_on' and 'clock_off' to NULL.
    <br><br>This should give me a rolling figure on the 'clock_off' field for clocked time.

  4. If the day is Mon, Tue, Wed or Thurs and 'clock_off' is NULL and the current time is 11pm then insert the current date and 16:15 into the 'clock_off' and run point #3.

  5. If the day is Fiday and 'clock_off' is NULL and the current time is 11pm then insert the current date and 12:15 into the 'clock_off' and run point #3.

Using Google and in the spirit of botching I've come up with the following.... which does not work. Can anyone help me out with a working trigger?

DELIMITER ;
DROP TRIGGER IF EXISTS `calculate_duration`;
DELIMITER $$
CREATE TRIGGER `calculate_duration`
AFTER INSERT
ON `events`
FOR EACH ROW
BEGIN
IF NEW.clock_on IS NOT NULL AND NEW.clock_off IS NOT NULL THEN
  UPDATE events
    SET time_clocked = UNIX_TIMESTAMP(NEW.clock_off) - UNIX_TIMESTAMP(NEW.clock_on)
    WHERE id = NEW.id;
END IF;
IF (
  DAYOFWEEK(CURRENT_DATE()) IN (1, 2, 3, 4)
  AND HOUR(NOW()) = 23
  AND NEW.clock_off IS NULL
) THEN
  INSERT INTO events (clock_on, clock_off)
    VALUES (CURRENT_DATE(), &#39;16:15&#39;);
END IF;
IF (
  DAYOFWEEK(CURRENT_DATE()) = 5
  AND HOUR(NOW()) = 23
  AND NEW.clock_off IS NULL
) THEN
  INSERT INTO events (clock_on, clock_off)
    VALUES (CURRENT_DATE(), &#39;12:15&#39;);
END IF;
END$$
DELIMITER;

Results of SHOW CREATE TABLE events

127.0.0.1/machines/events/		http://localhost/phpmyadmin/index.php?route=/table/sql&amp;db=machines&amp;table=events
Your SQL query has been executed successfully.

SHOW CREATE TABLE EVENTS;



EVENTS	CREATE TABLE `events` (
 &#160;`id` int(11) NOT NULL,
 &#160;`name` text DEFAULT NULL,
 &#160;`start` datetime DEFAULT NULL,
 &#160;`end` datetime DEFAULT NULL,
 &#160;`resource_id` int(11) DEFAULT NULL,
 &#160;`color` varchar(200) DEFAULT NULL,
 &#160;`join_id` int(11) DEFAULT NULL,
 &#160;`has_next` tinyint(1) NOT NULL DEFAULT 0,
 &#160;`TIMESTAMP` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
 &#160;`contract` text DEFAULT NULL,
 &#160;`part` text NOT NULL,
 &#160;`operation` text NOT NULL,
 &#160;`jobcard` text NOT NULL,
 &#160;`drawing` text DEFAULT NULL,
 &#160;`clock_on` datetime DEFAULT NULL,
 &#160;`clock_off` datetime DEFAULT NULL,
 &#160;`time_clocked` int(11) DEFAULT NULL,
 &#160;PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci	

答案1

得分: 0

如果存储在 time_clocked 中的值具有任何真正的业务价值,那么我建议您将各个 clock_on/clock_off 对存储在自己的表中,以便您维护证明 time_clocked 值的所需数据。

您可以使用类似以下的内容来维护 time_clocked 的值,就像您所描述的那样:

DELIMITER $$

CREATE TRIGGER `events_before_update_calculate_duration`
BEFORE UPDATE ON `events` FOR EACH ROW
BEGIN
    IF NEW.clock_on IS NOT NULL AND NEW.clock_off IS NOT NULL THEN
        SET NEW.time_clocked = COALESCE(OLD.time_clocked, 0) + TIMESTAMPDIFF(SECOND, NEW.clock_on, NEW.clock_off);
        SET NEW.clock_on = NULL, NEW.clock_off = NULL;
    END IF;
END$$

DELIMITER ;

注意使用 COALESCE() 处理您的 DEFAULT NULLtime_clocked

另外,要处理在 23:00 仍然打开的事件,您可以使用如下事件:

CREATE EVENT `event_clock_off_daily`
    ON SCHEDULE
      EVERY 1 DAY
      STARTS CURRENT_DATE + INTERVAL '23:00' HOUR_MINUTE
    COMMENT 'Clocks off events'
    DO
      UPDATE machines.events
      SET clock_off = CURRENT_DATE + INTERVAL IF(DAYOFWEEK(CURRENT_DATE) = 6, '12:15', '16:15') HOUR_MINUTE
      WHERE DAYOFWEEK(CURRENT_DATE) IN (2, 3, 4, 5, 6) -- 仅在周一至周五运行
      AND clock_on >= CURRENT_DATE
      AND clock_off IS NULL;

请注意 DAYOFWEEK()

返回日期的工作日索引(1 = 星期日,2 = 星期一,...,7 = 星期六)。这些索引值对应于ODBC标准。如果日期为NULL,则返回NULL。

英文:

If the value stored in time_clocked has any real business value, then I would suggest that you store the individual clock_on/clock_off pairs in their own table, so that you maintain the data required to evidence the value in time_clocked.


You could use something like this to maintain the value of time_clocked, as you have described:

DELIMITER $$

CREATE TRIGGER `events_before_update_calculate_duration`
BEFORE UPDATE ON `events` FOR EACH ROW
BEGIN
    IF NEW.clock_on IS NOT NULL AND NEW.clock_off IS NOT NULL THEN
        SET NEW.time_clocked = COALESCE(OLD.time_clocked, 0) + TIMESTAMPDIFF(SECOND, NEW.clock_on, NEW.clock_off);
        SET NEW.clock_on = NULL, NEW.clock_off = NULL;
    END IF;
END$$

DELIMITER ;

Note the use of COALESCE() to deal with your DEFAULT NULL for time_clocked.

And, to deal with clocking off events that are still clocked on at 23:00, you could use an event like:

CREATE EVENT `event_clock_off_daily`
    ON SCHEDULE
      EVERY 1 DAY
      STARTS CURRENT_DATE + INTERVAL &#39;23:00&#39; HOUR_MINUTE
    COMMENT &#39;Clocks off events&#39;
    DO
      UPDATE machines.events
      SET clock_off = CURRENT_DATE + INTERVAL IF(DAYOFWEEK(CURRENT_DATE) = 6, &#39;12:15&#39;, &#39;16:15&#39;) HOUR_MINUTE
      WHERE DAYOFWEEK(CURRENT_DATE) IN (2, 3, 4, 5, 6) -- only run Mon - Fri
      AND clock_on &gt;= CURRENT_DATE
      AND clock_off IS NULL;

Note that DAYOFWEEK():

> Returns the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday). These index values correspond to the ODBC standard. Returns NULL if date is NULL.

huangapple
  • 本文由 发表于 2023年5月25日 15:50:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76330013.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定