Query results are empty, output variable is correct - mysql

I am creating a stored procedure (routine) that selects multiple fields from a table and then sets a check/output variable.
Based on the data in my database, the check/output variable sets appropriately to the data being asked for, but my query does not return any actual data:
CREATE DEFINER=`odcorg_darrmik`#`%` PROCEDURE `sp_Get_Specific_Load`(
IN LOAD_ID INT,
OUT SUCCESS BIT)
BEGIN
set SUCCESS = 0;
SELECT
LOAD_ID,
DRIVER_ID,
BOL_NUMBER,
MILES,
LOAD_PAY,
SURCHARGE,
TARP_FEE,
DESCRIPTION,
WEIGHT,
TRUCK_NUMBER,
TRAILER_NUMBER,
HAZARDOUS,
DATE_RECEIVED,
DATE_DISPATCHED,
DATE_DUE,
DATE_DELIVERED,
BROKER_COMPANY,
BROKER_NAME,
TIME_APPOINTMENT,
TIME_ARRIVED,
TIME_STARTED,
TIME_FINISHED,
FCFS,
COMPLETE,
PAID_COMPANY,
PAID_DRIVER,
(SELECT NAME FROM customers inner join loads_info on loads_info.LOAD_ID = #LOAD_ID and customers.CUSTOMER_ID = loads_info.SHIPPER_ID) AS SHIPPER_NAME,
SHIPPER_ID,
(SELECT NAME FROM customers INNER JOIN loads_info ON loads_info.LOAD_ID = #LOAD_ID AND customers.CUSTOMER_ID = loads_info.CONSIGNEE_ID) AS CONSIGNEE_NAME,
CONSIGNEE_ID,
(SELECT FIRST_NAME + ' ' + LAST_NAME FROM employee inner join loads_info on loads_info.LOAD_ID = #LOAD_ID and EMPLOYEE_ID = DRIVER_ID) AS DRIVER_NAME,
(SELECT SIGNED_BOL FROM loads_documents INNER JOIN loads_info ON loads_info.LOAD_ID = #LOAD_ID and loads_documents.LOAD_ID = #LOAD_ID) AS SIGNED_BOL
FROM loads_info WHERE LOAD_ID = #LOAD_ID;
set SUCCESS = 1;
END
I have gone so far as to strip most everything from the query:
CREATE PROCEDURE sp_Get_Specific_Load(
IN LOAD_ID INT,
OUT SUCCESS BIT)
BEGIN
set SUCCESS = 0;
SELECT * FROM loads_info;
set SUCCESS = 1;
END
The above procedure will again return the SUCCESS output, but doesn't return anything from the
SELECT * FROM loads_info;
If I remove EVERYTHING leaving only the
SELECT * FROM loads_info;
The procedure will return data...if I add a WHERE clause (to the very simple query just above) I once again get no data...all the field headers but no data.
I am very new to MySQL... I converted this procedure from one that I wrote in MSSQL that functions as expected, returning the requested data and the check/output variable.
What have I done wrong??

It's your use of variables that you need to look at. The first thing to note is that #LOAD_ID in your WHERE clause is NOT the LOAD_ID you call your procedure with as the following example shows. #LOAD_ID is a completely separate variable and, since it's never set to anything, its value is NULL. The WHERE clause is therefore testing LOAD_ID = NULL, which will never be true, hence no rows are returned.
mysql> CREATE PROCEDURE `sp_Get_Specific_Load`(IN LOAD_ID INT, OUT SUCCESS BIT)
-> BEGIN
-> set SUCCESS = 0;
-> SELECT LOAD_ID, #LOAD_ID;
-> set SUCCESS = 1;
-> END //
mysql> SET #SUCCESS = 0;
mysql> CALL `sp_Get_Specific_Load` (999, #SUCCESS);
+---------+----------+
| LOAD_ID | #LOAD_ID |
+---------+----------+
| 999 | NULL |
+---------+----------+
1 row in set (0.01 sec)
mysql> SELECT #SUCCESS;
+----------+
| #SUCCESS |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
The second thing to avoid is using parameter names which match your column names. If you use the same name, MySQL pick the input parameter over the column name. As the next example shows it will pick the parameter, effectively testing the parameter value against itself (true for every row). So, you need to rename your input parameter to distinguish between the two.
mysql> CREATE TABLE LOADS_INFO (
-> LOAD_ID INT
-> );
mysql> INSERT INTO LOADS_INFO (LOAD_ID) VALUES (1),(2),(3),(4),(5),(999);
mysql> CREATE PROCEDURE `sp_Get_Specific_Load`(IN LOAD_ID INT, OUT SUCCESS BIT)
-> BEGIN
-> set SUCCESS = 0;
-> SELECT * FROM LOADS_INFO WHERE LOAD_ID = LOAD_ID;
-> set SUCCESS = 1;
-> END //
-- Matches ALL records with input of 999
mysql> CALL `sp_Get_Specific_Load` (999, #SUCCESS);
+---------+
| LOAD_ID |
+---------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 999 |
+---------+
6 rows in set (0.00 sec)

Related

How to use a MySQL stored procedure that generates a random 8-char long key to encrypt data again each time a the user logs in

I am working on a stored procedure in MySQL that is used to Login in a user for my polling application. I am trying to implement an algorithm that generates a new random 8-char long string that is being used as a new passphrase to re-encrypt data again.
In my particular case I am re-encrypting given answer-ids (aid) using this passphrase combined with AES. To re-encrypt the data that is already stored encrypted inside my database, the user provides his/her password to decrypt the 8-char long value that has already been stored inside the database. In other words the password is used to decrypt the old encryption-key so this key can be used to decrypt the answer-id of the question the user has voted on. Then the procedure generates a new 8-char long key to re-encrypt these answer-ids again each time the user has successfully logged in.
Unfortunately when I test my procedure, and I check the "vote" table I get NULL as the new encrypted answer id. I have done many attempts to correct this error and probably it has to do something with semantics but I haven't been able to solve it so far and I am puzzling very hard to find out what went wrong. The Login procedure calls another procedure that is responsible for extracting and decrypting already encrypted answer-ids, therefore it is using a while-loop that inserts data into a temporary table. Could you guys please help me out ?
In my opinion it is a slightly advanced procedure, maybe too advanced for my purposes. That's why I provided some comments that will lead you through all the steps being executed. This is my code:
LoginUser procedure
--------------------
-- LoginUser --
-- uname is stored encrypted by passwordhash,
-- pw is stored encrypted by unamehash,
-- key is encrypted by passwordhash,
-- aid is encrypted by key
--------------------
DROP PROCEDURE IF EXISTS LoginUser;
DELIMITER //
CREATE PROCEDURE LoginUser(IN uname CHAR(64), IN pw CHAR(64))
BEGIN
-- declare variables
DECLARE validUser, validLogin, validCombination BOOLEAN default 0;
DECLARE encryptedUsername, oldEncryptedKey, newEncryptedKey, encryptedPassword VARBINARY(32);
DECLARE plainOldKey, plainNewKey CHAR(8);
-- set encrypted username
SET encryptedUsername = (SELECT AES_ENCRYPT(uname,SHA2(pw,256)));
-- check if username exists - returns 1 for true, 0 for false
SET validUser = (SELECT EXISTS(SELECT username FROM user WHERE username = encryptedUsername));
-- logic when valid user
IF (validUser = 1) THEN
-- get pkey from user
SET oldEncryptedKey = (SELECT pkey FROM user WHERE username = encryptedUsername);
-- decrypt pkey using passwordhash
SET plainOldKey = (SELECT AES_DECRYPT(oldEncryptedKey, SHA2(pw,256)));
-- encrypt pw using plainOldKey
SET encryptedPassword = (SELECT AES_ENCRYPT(pw,SHA2(uname,256)));
-- check combination
SET validCombination = (SELECT EXISTS(SELECT * FROM user WHERE username = encryptedUsername AND `password` = encryptedPassword));
-- logic when valid combination
IF(validCombination = 1) THEN
-- set valid login to true
SET validLogin = 1;
-- generate a plainNewKey
SET plainNewKey = (SELECT SUBSTRING(MD5(RAND()) FROM 1 FOR 8));
-- set new encrypted key
SET newEncryptedKey = (SELECT AES_ENCRYPT(plainNewKey,SHA2(pw,256)));
-- call procedure to re-encrypt answer ids.
CALL EncryptAidsAgain(plainOldKey,plainNewKey,encryptedUsername);
-- update pkey from user table by newKey
UPDATE user SET pkey = newEncryptedKey WHERE username = encryptedUsername;
END IF;
END IF;
SELECT validLogin;
END //
DELIMITER ;
EncryptAidsAgain procedure
DROP PROCEDURE IF EXISTS EncryptAidsAgain;
DELIMITER //
CREATE PROCEDURE EncryptAidsAgain(IN oldKeyValue CHAR(8), IN newKeyValue CHAR(8), IN encryptedUsername VARBINARY(32))
BEGIN
DECLARE i, answered INT DEFAULT 0;
DECLARE encryptedAid, newEncryptedAid VARBINARY(32);
DECLARE plainAid CHAR(7);
-- create temporary table to store aids
CREATE TEMPORARY TABLE aids(oldEncryptedAid VARBINARY(32));
-- get amount of given answers
SET answered = (SELECT COUNT(*) FROM vote WHERE username = encryptedUsername);
-- perform while loop
WHILE i < answered DO
-- insert single aid in temporary table aids
INSERT INTO aids (oldEncryptedAid) SELECT aid FROM vote WHERE username = encryptedUsername LIMIT i, 1;
-- retrieve stored aid from aids
SET encryptedAid = (SELECT oldEncryptedAid FROM aids LIMIT i, 1);
-- decrypt stored aid from aids using oldKeyValue
SET plainAid = (SELECT AES_DECRYPT(encryptedAid, SHA2(oldKeyValue,256)));
-- set new encrypted aid
SET newEncryptedAid = (SELECT AES_ENCRYPT(plainAid,SHA2(newKeyValue,256)));
-- update table vote (aid)
UPDATE vote SET aid = newEncryptedAid WHERE username = encryptedUsername AND aid = encryptedAid;
-- increase i
SET i = i + 1;
END WHILE;
DROP TABLE aids;
END //
DELIMITER ;
test results
When call the LoginUser procedure multiple times each time the key updates well:
mysql> select * from user;
+------------------+------------------+------------------+------------------------------------------------------------------+
| username | password | pkey | ip |
+------------------+------------------+------------------+------------------------------------------------------------------+
| EÞ¯k·\â¥çJ¤EÃîP | EÞ¯k·\â¥çJ¤EÃîP | 6░ÛõaǪhpK║ÔäV | 26b92be7c4ad202f842d1755c3db56f25b39c54c51cc56642b8f14ba4bda793d |
+------------------+------------------+------------------+------------------------------------------------------------------+
4 rows in set (0.00 sec)
mysql> call LoginUser("test4","test4");
+------------+
| validLogin |
+------------+
| 1 |
+------------+
1 row in set (0.02 sec)
Query OK, 0 rows affected (0.02 sec)
mysql> select * from user;
+------------------+------------------+------------------+------------------------------------------------------------------+
| username | password | pkey | ip |
+------------------+------------------+------------------+------------------------------------------------------------------+
| EÞ¯k·\â¥çJ¤EÃîP | EÞ¯k·\â¥çJ¤EÃîP | ┴O¥╝Îìöãñ#='¹ | 26b92be7c4ad202f842d1755c3db56f25b39c54c51cc56642b8f14ba4bda793d |
+------------------+------------------+------------------+------------------------------------------------------------------+
4 rows in set (0.00 sec)
But when I login the user multiple times, the new encrypted answer-ids go NULL
mysql> select * from vote;
+-----+------------------+------+------------------+
| vid | username | qid | aid |
+-----+------------------+------+------------------+
| 3 | EÞ¯k·\â¥çJ¤EÃîP | 2 | ðlözaò3OîÙW▓B═Ï |
| 4 | EÞ¯k·\â¥çJ¤EÃîP | 1 | z)ı╝├║%~╝V&7#"─V |
+-----+------------------+------+------------------+
2 rows in set (0.00 sec)
mysql> call LoginUser("test4","test4");
+------------+
| validLogin |
+------------+
| 1 |
+------------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
mysql> select * from vote;
+-----+------------------+------+------+
| vid | username | qid | aid |
+-----+------------------+------+------+
| 3 | EÞ¯k·\â¥çJ¤EÃîP | 2 | NULL |
| 4 | EÞ¯k·\â¥çJ¤EÃîP | 1 | NULL |
+-----+------------------+------+------+
2 rows in set (0.00 sec)
Thank you very much in advance, if you have any tips for a better encryption policy they are very welcome!

MySQL duplicate data removal with loop

I have a table called Positions which has data like this:
Id PositionId
1 'a'
2 'a '
3 'b '
4 'b'
Some of them has spaces so my idea is to remove those spaces, this is not actual table just an example of a table which has much more data.
So i created procedure to iterate over PositionIds and compare them if trimed they match remove one of them:
CREATE PROCEDURE remove_double_positions()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE current VARCHAR(255);
DECLARE previous VARCHAR(255) DEFAULT NULL;
DECLARE positionCur CURSOR FOR SELECT PositionId FROM Positions ORDER BY PositionId;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN positionCur;
clean_duplicates: LOOP
FETCH positionCur INTO current;
IF done THEN
LEAVE clean_duplicates;
END IF;
IF previous LIKE current THEN
DELETE FROM Positions WHERE PositionId = current;
END IF;
SET previous = current;
END LOOP clean_duplicates;
CLOSE positionCur;
END
For some reason it shows that 2 rows were affected but actually deletes all 4 of them and i don't know the reason why, could you help me.
From the manual https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html#operator_like under the like operator - Per the SQL standard, LIKE performs matching on a per-character basis, thus it can produce results different from the = comparison operator:...In particular, trailing spaces are significant, which is not true for CHAR or VARCHAR comparisons performed with the = operator:
mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
| 1 | 0 |
+------------+---------------+
1 row in set (0.00 sec)
This is true when = or like is used in where or case.
Your procedure would work as desired if you amended the delete bit to
IF trim(previous) = trim(current) THEN
DELETE FROM Positions WHERE PositionId like current;
END IF;
Just some other solution without cursor and procedure. I've check it on ORACLE. Hope it helps.
DELETE FROM positions
WHERE id IN ( SELECT t1.id
FROM positions t1,
positions t2
WHERE t1.positionId = TRIM(t2.positionId)
AND t1.positionId != t2.positionId
);
UPDATE
There are some crasy things are going on with mysql. Some problem with blank at the end of a strong and this error 1093 error.
Now my solution checked with MySQL 5.5.9
CREATE TABLE positions (
id INT NOT NULL,
positionid VARCHAR(2) NOT NULL
);
INSERT INTO positions VALUES
( 1, 'a'),
( 2, 'a '),
( 3, 'b'),
( 4, 'b ');
DELETE FROM positions
WHERE id IN ( SELECT t3.id FROM
(SELECT t2.id
FROM positions t1,
positions t2
WHERE t1.positionid = t2.positionid
AND LENGTH(t1.positionid) = 1
AND length(t2.positionid) = 2
) t3
);
mysql> SELECT * from positions;
+----+------------+
| id | positionid |
+----+------------+
| 1 | a |
| 3 | b |
+----+------------+
2 rows in set (0.00 sec)
mysql>
This "double" from delete SQL will fix this error 1093
Hope this helps.

how to get the updated row from a table when calling a trigger after update

This is my table structure
mysql> select * from product_table;
+----------------+---------------------+
| product_number | product_description |
+----------------+---------------------+
| 1 | product one |
| 2 | product two |
| 3 | product three |
| 9 | product five |
| 10 | product six |
| 11 | product six |
+----------------+---------------------+
I want to say update a row say 9th product number from the table like this
UPDATE product_table SET product_description ="product seven" WHERE product_number=9;
So that in the trigger i can get the corresponding updated product number from the table product_table
I wrote the trigger like this and it got created without any errors.
DELIMITER //
CREATE TRIGGER product_table_update
AFTER UPDATE
ON product_table
FOR EACH ROW
BEGIN
DECLARE l_product_number INT;
set #l_table_name = 'product_table';
set #l_action = 'updation';
SET #l_table_column = 'product_description';
select new.product_number into #l_product_number from product_table;// here is i think where the problem is , i am trying to fetch the updated row to l_product_number
IF (OLD.product_description <> NEW.product_description) THEN
SET #oldval = OLD.product_description;
SET #newval = NEW.product_description;
select concat(#oldval,#newval) into #l_description;
END IF;
INSERT INTO audit_table_test
( table_name,
changed_row_id,
action,
table_column,
change_desciption,
change_time
)
VALUES
( #l_table_name,
#l_product_number,
#l_action,
#l_table_column,
#l_description,
NOW()
);
END; //
DELIMITER ;
then when i tried to update like this
UPDATE product_table SET product_description ="product seven" WHERE product_number=11;
This error is showing
ERROR 1172 (42000): Result consisted of more than one row
I know the problem has to be in this code
select new.product_number into #l_product_number from product_table;// here is i think where the problem is , i am trying to fetch the updated row to l_product_number
Please someone help me to get the update row on calling this trigger
Try:
...
SET #l_table_column = 'product_description';
/*
here is i think where the problem is , i am trying to fetch the
updated row to l_product_number
*/
-- select new.product_number into #l_product_number from product_table;
SET #l_product_number := NEW.product_number;
IF (OLD.product_description <> NEW.product_description) THEN
...

mysql procedure function returning error

I'm trying to create a mysql function, but i keep getting following error. What is the problem with my query?
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BEGIN INSERT INTO order (carID, clientID) Select car.id, client.id FROM' at line 2
My query:
DELIMITER //
CREATE FUNCTION orderCreate(LicenseNumber varchar(30), Phonenumber varchar(20))
BEGIN
INSERT INTO `order` (carID, clientID) Select car.id, client.id FROM car, client, owns WHERE car.licensenumber = LicenseNumber AND client.phonenumber = Phonenumber AND car.id = owns.carID AND owns.clientID = client.id;
RETURN mysql_insert_id();
END //
DELIMITER ;
FUNTION definition signature must have a RETURNS clause.
Your code did not use it.
And you can't use mysql_insert_id() within MySQL but PHP.
You have to use LAST_INSERT_ID().
Function:
delimiter //
drop function if exists orderCreate //
CREATE FUNCTION orderCreate( _LicenseNumber varchar(30), _Phonenumber varchar(20) )
RETURNS INTEGER
BEGIN
INSERT
INTO `order` ( carID, clientID )
SELECT car.id, client.id
FROM car, client, owns
WHERE car.licensenumber = _LicenseNumber
AND client.phonenumber = _Phonenumber
AND car.id = owns.carID
AND owns.clientID = client.id;
RETURN LAST_INSERT_ID();
END;
//
delimiter ;
And it would be a better practice to use different function/procedural parameter names over column names. Because unless used table name qualifiers with column names, there would arise an ambiguity in recognizing them and priority may be given to parameter names over column names.
select phonenumber from client;
Above statement may result all rows with input value PhoneNumber but not what you expected.
Example:
mysql> create procedure sp_so_q23838311( in deptno int )
-> select deptno from department
-> union all
-> select department.deptno from department;
Query OK, 0 rows affected (0.00 sec)
mysql> select deptno from department;
+--------+
| deptno |
+--------+
| 10 |
| 20 |
| 30 |
| 40 |
+--------+
4 rows in set (0.00 sec)
mysql> call sp_so_q23838311( 20 );
+--------+
| deptno |
+--------+
| 20 |
| 20 |
| 20 |
| 20 |
| 10 |
| 20 |
| 30 |
| 40 |
+--------+
8 rows in set (0.15 sec)
Documentation on FUNCTION:
CREATE FUNCTION Syntax for User-defined Functions
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name

Launch Trigger and Routine on Insert

Im attempting to have MySQL automatically insert data into another table after insert into one. I know to do this required Triggers and potentially Routines. I have a couple I've been trying to modify to do what I wish to accomplish but I appear to be hitting a dead end due to lack of experience, so help is greatly appreciated.
The table that has data inserted (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
There are a couple of other columns here, that separate out by time, but I'm interested by day, rather than time.
Table data should go into compounded. So as each of the above rows are inserted, it will either create a new row if the tou_tracking_start and ICP_ID do not exist, or update the existing row.
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
Below is my Tigger (no errors when setup on MySQL, and it does appear to call when data is attempted to be inserted):
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
and then the routine it calls to calculate units.
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
The routine throws back an error on line 3 when I try to run the SQL to setup the routine, but I can't see anything obviously wrong, but I'm not exactly sure what I'd be looking for.
Any help with this is hugely appreciated and any pointers that can be given along the way. Thanks :)
Attempting to replicate your issue, I'm going to guess the error you get is probably because you're not using a DELIMITER.
Executing a similar function creation statement I get the same error, and a syntax parse suggests it's not expecting the delimiter ;.
The one that causes an error on line 3.
CREATE DEFINER = 'root'#'localhost' FUNCTION test_func(foo INT) RETURNS FLOAT
BEGIN
DECLARE bar FLOAT;
RETURN 1;
END
Fixing it using delimiters.
DELIMITER $$
CREATE DEFINER = 'root'#'localhost' FUNCTION test_func(foo INT) RETURNS FLOAT
BEGIN
DECLARE bar FLOAT;
RETURN 1;
END$$
DELIMITER ;
If this does not fix your problem, are you able to provide a self contained function that doesn't rely on any of your existing tables, that also produces the same error so it can be tested?
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)