Оператор вставки JDBC не запускает триггеры и функции на MySQL - PullRequest
1 голос
/ 19 ноября 2011

У меня есть триггер и функция, как указано ниже

Триггер:

DELIMITER $$

USE `server`$$

DROP TRIGGER /*!50032 IF EXISTS */ `calcQumilative`$$

CREATE
    /*!50017 DEFINER = 'root'@'%' */
    TRIGGER `calcQumilative` BEFORE INSERT ON `cpdata` 
    FOR EACH ROW BEGIN
    DECLARE curr_distance DECIMAL(12,4) DEFAULT 0;
    DECLARE prev_id  INT;
    DECLARE prev_lat  DECIMAL(12,7);
    DECLARE prev_lon  DECIMAL(12,7);
    DECLARE prev_idling  INT;
    DECLARE prev_idlingcount  INT;
    DECLARE prev_ignition  INT;
    DECLARE prev_ignitioncount  INT;
    DECLARE prev_fuelconsumption  DECIMAL(12,4);
    DECLARE prev_dist  DECIMAL(12,4);
    DECLARE prev_infuel DECIMAL(12,4);
    DECLARE prev_outfuel DECIMAL(12,4);
    DECLARE prev_hw_infuel DECIMAL(12,4);
    DECLARE prev_hw_outfuel DECIMAL(12,4);
    DECLARE prev_tmp_idl_fuel DECIMAL(12,4) DEFAULT 0;
    DECLARE curr_idling  INT;
    DECLARE curr_idlingcount  INT DEFAULT 0;
    DECLARE curr_ignition  INT;
    DECLARE curr_ignitioncount  INT;    
    DECLARE curr_fuelconsumption  DECIMAL(12,4);
    DECLARE curr_idl_fuelconsumption  DECIMAL(12,4)DEFAULT 0;
    DECLARE curr_tmp_idl_fuel DECIMAL(12,4) DEFAULT 0;
    DECLARE curr_infuel  DECIMAL(12,4);
    DECLARE curr_outfuel  DECIMAL(12,4);
    DECLARE temprowcount INT  DEFAULT 1 ;

    SELECT id,latitude ,longitude,idling,idlingcount,ignition,ignitioncount,idlingfuelconsumption,distance,infuel_pulsecount,
        outfuel_pulsecount,hw_infuel_pulsecount,hw_outfuel_pulsecount,tmp_idlingfuelconsumption INTO 
        prev_id,prev_lat,prev_lon,prev_idling,prev_idlingcount,prev_ignition,prev_ignitioncount,prev_fuelconsumption,prev_dist,prev_infuel,
        prev_outfuel,prev_hw_infuel,prev_hw_outfuel,prev_tmp_idl_fuel FROM carbonpoddata AS prevrow
    WHERE prevrow.id < NEW.id AND NEW.vehicalnum = prevrow.vehicalnum AND DATE (NEW.podtimestamp) = DATE(prevrow.podtimestamp) ORDER BY podtimestamp DESC LIMIT 1;          
    IF prev_id IS NOT NULL THEN 

        IF NEW.hw_infuel_pulsecount > prev_hw_infuel THEN
            SET curr_infuel = prev_infuel + (NEW.hw_infuel_pulsecount - prev_hw_infuel) ;
        ELSE
            SET curr_infuel = prev_infuel + (100- prev_hw_infuel) + NEW.hw_infuel_pulsecount ;
        END IF;
        IF NEW.hw_outfuel_pulsecount > prev_hw_outfuel THEN
            SET curr_outfuel = prev_outfuel + (NEW.hw_outfuel_pulsecount - prev_hw_outfuel) ;
        ELSE
            SET curr_outfuel = prev_outfuel + (100- prev_hw_outfuel) + NEW.hw_outfuel_pulsecount ;
        END IF;
        IF prev_ignition = NEW.ignition THEN
            SET curr_ignitioncount = (prev_ignitioncount+1);
        ELSE
            SET curr_ignitioncount = 1;
        END IF;
        IF ( prev_lat = NEW.latitude AND prev_lon = NEW.longitude AND NEW.ignition = 1) THEN
            SET curr_idling = 1;
            IF prev_idling = curr_idling THEN
                SET curr_idlingcount  = prev_idlingcount+1 ;                
                SET curr_fuelconsumption  = prev_tmp_idl_fuel + (((curr_infuel - curr_outfuel)* 5) /1000 ) ;        
                IF curr_idlingcount = 10 THEN 
                     SET curr_idl_fuelconsumption = curr_fuelconsumption;
                ELSE 
                    IF curr_idlingcount > 10 THEN 
                        SET curr_idl_fuelconsumption = (((curr_infuel - curr_outfuel)* 5) /1000 ) ;
                    ELSE
                        SET curr_tmp_idl_fuel = curr_fuelconsumption;
                    END IF;
                END IF;

            ELSE                
                SET curr_idlingcount  = 1;

            END IF;         
        ELSE
            SET curr_idling = 0;
            IF prev_idling = curr_idling THEN
                SET curr_idlingcount  = prev_idlingcount+1 ;                

            ELSE                
                SET curr_idlingcount  = 1;

            END IF;                     
        END IF;     
        SELECT CALCULATE_DISTANCE(prev_lat,prev_lon,NEW.latitude,NEW.longitude) INTO curr_distance;
        IF curr_distance IS NULL THEN 
            SET curr_distance = 0;
        END IF;
        SET curr_distance = curr_distance + prev_dist;                  
        SET NEW.distance = curr_distance;
        SET NEW.ignitioncount =curr_ignitioncount ;
        SET NEW.idlingcount =curr_idlingcount;
        SET NEW.idling = curr_idling;   
        SET NEW.infuel_pulsecount = curr_infuel;
        SET NEW.outfuel_pulsecount = curr_outfuel;
        SET NEW.tmp_idlingfuelconsumption = curr_tmp_idl_fuel;
        SET NEW.idlingfuelconsumption = curr_idl_fuelconsumption;


    END IF;
    END;
$$

DELIMITER ;

Выше триггера есть вызов функции CALCULATE_DISTANCE:

DELIMITER $$

USE `server`$$

DROP FUNCTION IF EXISTS `CALCULATE_DISTANCE`$$

CREATE DEFINER=`root`@`%` FUNCTION `CALCULATE_DISTANCE`(`@oLat` DECIMAL(10,7), `@oLon` DECIMAL(10,7), `@dLat` DECIMAL(10,7), `@dLon` DECIMAL(10,7)) RETURNS DECIMAL(10,7)
    NO SQL
BEGIN
    RETURN (
        (
            ACOS(
                SIN(`@dLat` * PI() / 180) *
                SIN(`@oLat` * PI() / 180) +
                COS(`@dLat` * PI() / 180) *
                COS(`@oLat` * PI() / 180) *
                COS((`@dLon` - `@oLon`) * PI() / 180)
            ) *
            180 / PI()
        ) *
        60 *
        1.1515 *
        1.609344
    );
    END$$

DELIMITER ;

Когда я вставляю запись в таблицу cpdata, она должна была запускать триггер перед вставкой, но похоже, что MySQL не распознал это, когда я использовал Hibernate и JDBC для вставки записи.

НоТриггер работает правильно, если я вставляю несколько записей, используя SQLYog.В чем может быть причина и как я могу ее решить?

1 Ответ

0 голосов
/ 03 января 2012

У меня точно такая же проблема.Я нашел причину этого, но не лекарство.

Когда соединение в конечном итоге выбирается из DriverManager.getConnection (), MySQL JDBC Connection автоматически выполняет следующее:

SET sql_mode='STRICT_TRANS_TABLES'

Я пока не нашел способ его отключить.Одним из решений было бы выполнить это перед выполнением любого SQL

SET sql_mode=''

Но, вероятно, это не так просто в среде ORM, как Hibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...