0

我有这个查询,它尝试在提交插入后更新另一个表中的几个值。在触发器内部有一个被调用的函数calc_distance,它返回一个DOUBLE类型的值。

因此,问题在于,无论我是否正确调用该函数,更新都不会采用返回值。我测试了与 mysql 命令提示符分开运行它的函数,实际上它返回了预期的计算。

那么有人可以告诉我这个查询发生了什么吗?

    DELIMITER ;;
    TRIGGER `DB1`.`update_coords`
    AFTER INSERT ON `DB1`.`TABLE_tracking`
    FOR EACH ROW
    BEGIN
    DECLARE LAT1, LAT2, LNG1, LNG2, DISTANCE DOUBLE;
    UPDATE TABLE_vehiculos SET ultima_comunicacion = now(),
    googlelat=(IF(NEW.latitude<>0,NEW.latitude,googlelat)), googlelong=(IF(NEW.longitude<>0,NEW.longitude,googlelong)),
    tipo_data=NEW.command, reported_command=(IF(NEW.valid=1,"F","A")), velocidad=NEW.speed, status="A",

    /* HERE COMES THE FUNCTION THAT IS NOT DOING ANYTHING */
    odometro=odometro+calc_distance(googlelat,NEW.latitude,googlelong,NEW.lontitude)
    /* --------------------------------------------------- */

    WHERE imei = NEW.device_id;
    END ;;
    DELIMITER ;

我声明LAT1, LAT2, LNG1, LNG2,DISTANCE用 NEW.latitude 等设置所有这些变量,但我意识到我无法对这些变量做任何事情,因为我无法访问 NEW.latitude 和值googlelat,或者googlelong直到我调用 update tableX,所以,什么是继续?我测试了calc_distance这样的功能:

    mysql> select calc_distance(9.104550000000, 9.102577000000, -79.370780000000, -79.3622423000000);
    +------------------------------------------------------------------------------------+
    | calc_distance(9.104550000000, 9.102577000000, -79.370780000000, -79.3622423000000) |
    +------------------------------------------------------------------------------------+
    |                                                                 0.9627214584265752 |
    +------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)

在过去的 6 个小时里,我一直在用头撞显示器,请帮忙!!

    DELIMITER ;;
    CREATE FUNCTION `calc_distance`(`lat1` DOUBLE, lat2 DOUBLE, lng1 DOUBLE, lng2 DOUBLE)
    RETURNS DOUBLE
    BEGIN
        DECLARE radio INTEGER(5);
        DECLARE distance DOUBLE;
        set radio = 6371;
            SELECT radio * 2 * ASIN
            ( SQRT (POWER(SIN((lat1 - lat2)*pi()/180 / 2),2) +
            COS(lat1 * pi()/180) * COS(lat2 *pi()/180) *
            POWER(SIN((lng1 - lng2) *pi()/180 / 2), 2) ) ) into distance;
        RETURN distance;
    END ;;
    DELIMITER ;
4

2 回答 2

1

如果我理解正确,请尝试

CREATE TRIGGER `DB1`.`update_coords`
AFTER INSERT ON `DB1`.`TABLE_tracking`
FOR EACH ROW
    UPDATE TABLE_vehiculos 
       SET ultima_comunicacion = NOW(),
           googlelat  = IF(NEW.latitude <> 0, NEW.latitude, googlelat), 
           googlelong = IF(NEW.longitude <> 0, NEW.longitude, googlelong),
           tipo_data  = NEW.command, 
           reported_command = IF(NEW.valid = 1, 'F', 'A'),
           velocidad  = NEW.speed, 
           status = 'A',
           odometro = odometro + 
                      calc_distance(IF(NEW.latitude <> 0, NEW.latitude, googlelat),
                                    NEW.latitude,
                                    IF(NEW.longitude <> 0, NEW.longitude, googlelong),
                                    NEW.lontitude)
     WHERE imei = NEW.device_id;

仅供参考:现在它是一个单语句触发器,因此您无需更改DELIMITER和使用BEGIN...END块。

于 2013-09-25T06:05:21.760 回答
0

这是最好的解决方案,而不是尝试从另一个表更新,为什么不直接从受影响的表更新呢?

    DELIMITER ;;
    CREATE TRIGGER `DB1`.`update_distances`
    BEFORE UPDATE ON `DB1`.`tb_vehiculos`
    FOR EACH ROW
    BEGIN
    SET @DISTANCE = calc_distance(OLD.googlelat,NEW.googlelat,OLD.googlelong,NEW.googlelong);
    SET NEW.odometro = OLD.odometro + @DISTANCE;
    END ;;
    DELIMITER ;
于 2013-09-26T06:54:26.733 回答