1

我试图让 MySQL 在插入一个表后自动将数据插入另一个表。我知道这样做需要触发器和潜在的例程。我有几个我一直在尝试修改以完成我希望完成的工作,但由于缺乏经验,我似乎陷入了死胡同,因此非常感谢您的帮助。

插入数据的表(db_tou_tracking):

 tou_tracking_ID  ICP_ID  tou_tracking_start  tou_tracking_units
 ----------------------------------------------------------------
      2             2        2013-03-01            10.77
      3             2        2013-03-01            11.00

这里还有其他几列,按时间分开,但我感兴趣的是一天,而不是时间。

表数据应进入复合。因此,当插入上述每一行时,如果 tou_tracking_start 和 ICP_ID 不存在,它将创建一个新行,或者更新现有行。

  tou_tracking_daily_ID  ICP_ID  tou_tracking_start  tou_tracking_units
 ------------------------------------------------------------------------------
             1             2        2013-03-01            21.77
             2             2        2013-03-02            25.36

下面是我的 Tigger(在 MySQL 上设置时没有错误,并且在尝试插入数据时它确实会调用):

BEGIN 
DECLARE presentcount INT;
SET presentcount = (SELECT count(*) FROM db_tou_tracking_daily WHERE tou_tracking_daily_day = 
        (SELECT tou_tracking_start FROM db_tou_tracking WHERE ICP_ID = db_tou_tracking_daily.ICP_ID ORDER BY tou_tracking_ID DESC)
    );
    IF (presentcount = 0) THEN
        INSERT INTO db_tou_tracking_daily (ICP_ID, tou_tracking_daily_day, tou_tracking_start)
            SELECT NEW.ICP_ID, NEW.tou_tracking_start, NEW.tou_tracking_units, calculate_units(NEW.ICP_ID, NEW.tou_tracking_start);
    ELSE 
        UPDATE db_tou_tracking_daily SET tou_tracking_daily_units = calculate_units(NEW.ICP_ID, tou_tracking_daily_day)
            WHERE ICP_ID = NEW.ICP_ID AND tou_tracking_daily_day = NEW.tou_tracking_start;
    END IF;

END

然后是它调用的计算单位的例程。

    CREATE DEFINER=`root`@`localhost` FUNCTION `calculate_units`(ICP_ID INT, tou_tracking_daily_day DATE) RETURNS float
BEGIN
    DECLARE units FLOAT;
    DECLARE last_time DATE;
    DECLARE last_watts INT;
    DECLARE this_time DATETIME;
    DECLARE this_watts INT;
    DECLARE loop_done INT;
    DECLARE curs CURSOR FOR 
        SELECT tou_tracking_timestart, tou_tracking_units FROM db_tou_tracking WHERE ICP_ID = ICP_ID AND tou_tracking_start = tou_tracking_daily_day ORDER BY tou_tracking_start DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET loop_done = 1;

        SET last_time = (SELECT max(tou_tracking_start) FROM db_tou_tracking WHERE ICP_ID = ICP_ID AND tou_tracking_start < tou_tracking_daily_day);
        SET last_watts = (SELECT tou_tracking_units FROM db_tou_tracking WHERE ICP_ID = ICP_ID AND tou_tracking_start = last_time);
        SET last_time = CAST(tou_tracking_start AS DATETIME);

        SET loop_done = 0;
        SET units = 0;

        OPEN curs;
        REPEAT
            FETCH curs INTO this_time, this_watts;

            IF last_watts IS NOT NULL THEN
                SET units = units + (last_watts + this_watts);
            END IF;
            SET last_watts = this_watts;
            SET last_time = this_time;
        UNTIL loop_done END REPEAT;
        CLOSE curs;
    END

当我尝试运行 SQL 来设置例程时,例程在第 3 行返回一个错误,但我看不到任何明显错误的地方,但我不确定我要寻找什么。

对此的任何帮助都非常感谢,并且可以在此过程中给出任何指示。谢谢 :)

4

2 回答 2

0

create table t1 ( start date not null, units decimal(5,2) not null );

create table t2 ( start date not null, units decimal(5,2) not null );

delimiter //

create trigger trg1 after insert on t1 for each row begin update t2 set units = units + new.units where start = new.start; if ROW_COUNT() = 0 then insert into t2 (start, units) values (new.start, new.units); end if; end //

delimiter ; //

mysql> select * from t1; Empty set (0.01 sec)

mysql> select * from t2; Empty set (0.00 sec)

mysql> insert into t1 (start, units) values ('2014-01-01',100.02); Query OK, 1 row affected (0.01 sec)

mysql> select * from t1; +------------+--------+ | start | units | +------------+--------+ | 2014-01-01 | 100.02 | +------------+--------+ 1 row in set (0.00 sec)

mysql> select * from t2; +------------+--------+ | start | units | +------------+--------+ | 2014-01-01 | 100.02 | +------------+--------+ 1 row in set (0.00 sec)

mysql> insert into t1 (start, units) values ('2014-01-01',200.05); Query OK, 1 row affected (0.01 sec)

mysql> select * from t1; +------------+--------+ | start | units | +------------+--------+ | 2014-01-01 | 100.02 | | 2014-01-01 | 200.05 | +------------+--------+ 2 rows in set (0.01 sec)

mysql> select * from t2; +------------+--------+ | start | units | +------------+--------+ | 2014-01-01 | 300.07 | +------------+--------+ 1 row in set (0.01 sec)

于 2014-05-12T13:32:41.307 回答
0

试图复制你的问题,我猜你得到的错误可能是因为你没有使用DELIMITER.

执行一个类似的函数创建语句我得到了同样的错误,并且语法分析表明它不需要 delimiter ;

导致第 3 行错误的那个。

CREATE DEFINER = 'root'@'localhost' FUNCTION test_func(foo INT) RETURNS FLOAT
BEGIN
    DECLARE bar FLOAT;
    RETURN 1;
END

使用分隔符修复它。

DELIMITER $$
CREATE DEFINER = 'root'@'localhost' FUNCTION test_func(foo INT) RETURNS FLOAT
BEGIN
    DECLARE bar FLOAT;
    RETURN 1;
END$$
DELIMITER ;

如果这不能解决您的问题,您是否能够提供一个不依赖任何现有表的自包含函数,它也会产生相同的错误以便对其进行测试?

于 2014-05-12T00:45:28.573 回答