Declaring a variable in mysql trigger - mysql

I have a MySQL trigger that is being used to call the rsaencrypt function to encrypt a particular value.
DELIMITER $$
CREATE TRIGGER ssninsertencrypt BEFORE INSERT ON redcap_data
FOR EACH ROW
BEGIN
IF new.project_id = (SELECT ProjectID FROM redcap_encryption)
AND new.field_name = (SELECT FieldName FROM redcap_encryption)
THEN
SET #PublicKey = (SELECT PublicKey FROM redcap_encryption WHERE ProjectID = new.project_id);
SET new.value = rsaencrypt(new.value,#PublicKey);
END IF;
END$$
DELIMITER ;
This seems to be inconsistently working/not working so i'd like to insert the completed statement the trigger produces into another table so can see what is being passed to the rsaencrypt or not passed. I thought i could just do a SET #SQL () like the following
SET #SQL =
(IF new.project_id = (SELECT ProjectID FROM redcap_encryption)
AND new.field_name = (SELECT FieldName FROM redcap_encryption)
THEN
SET #PublicKey = (SELECT PublicKey FROM redcap_encryption WHERE ProjectID = new.project_id);
SET new.value = rsaencrypt(new.value,#PublicKey);
END IF;)
I get syntax errors on this and i'm unsure how best to proceed
Thanks

Resolved this a while ago but forgot to post :-
BEGIN
IF new.field_name = (SELECT FieldName FROM redcap_encryption WHERE new.project_id = ProjectID)
THEN
SET #PublicKey = (SELECT PublicKey FROM redcap_encryption WHERE ProjectID = new.project_id);
SET new.value = rsaencrypt(new.value,#PublicKey);
END IF;
END$$

Related

return null value in the JSON_EXTRACT

MyJsonArray
[{"ID":"D29","PersonID":"23616639"},{"ID":"D30","PersonID":"22629626"}]
and I want from sql Function set this array in to my Table but return null value in the variable and not set record in My database
my function:
DELIMITER $$
CREATE DEFINER=`toshiari`#`localhost` FUNCTION `setTitleRecords`(`Title` VARCHAR(166) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `List` JSON) RETURNS int(4)
BEGIN
DECLARE Item INT;
DECLARE HolderLENGTH INT;
DECLARE ValidJson INT;
DECLARE ID VARCHAR(166);
DECLARE PersonID VARCHAR(166);
DECLARE S1 VARCHAR(166);
DECLARE S2 VARCHAR(166);
SET ValidJson = (SELECT JSON_VALID(List));
IF ValidJson = 1 THEN
SET HolderLENGTH = (SELECT JSON_LENGTH(List));
SET Item = 0;
WHILE Item < HolderLENGTH DO
SET S1 = CONCAT("'$[",Item, "].ID'");
SET S2 = CONCAT("'$[",Item, "].PersonID'");
SET ID = (SELECT JSON_EXTRACT(List,S1));
SET PersonID = (SELECT JSON_EXTRACT(List,S2));
INSERT INTO `Titles`(`ID`,`PersonID`,`Title`) VALUES (ID, PersonID, Title);
SET Item = Item + 1;
END WHILE;
RETURN 3;
ELSE
RETURN 2;
END IF;
END$$
DELIMITER ;
when I use this command in the Sql commands no problem and return true value
SELECT JSON_EXTRACT('[{"ID":"D29","PersonID":"23616639"},{"ID":"D30","PersonID":"22629626"}]','$[0].ID') return "D29"
return
"D29"
but in when run function from this code
return error and said:
SET #p0='DR'; SET #p1='[{\"ID\":\"D29\",\"PersonID\":\"23616639\"},{\"ID\":\"D30\",\"PersonID\":\"22629626\"}]'; SELECT `setTitleRecords`(#p0, #p1) AS `setTitleRecords`;
#4042 - Syntax error in JSON path in argument 2 to function 'json_extract' at position 1
I created a little test, in order to reproduce your issues. Basically you just need to redeclare S1 and S2, in the following way:
SET S1 = CONCAT('$[',Item,'].ID');
SET S2 = CONCAT('$[',Item,'].PersonID');
And that's it. You can check the test in the following url: https://www.db-fiddle.com/f/2TPgF868snjwcHN3uwoSEA/0

What does "The following query failed" ";"" mean in MySQL?

While trying to update a trigger, MySQL tells me the query ";" failed. How is ";" even a query in MySQL's view is beyond me.
The exact message is:
The following query has failed: ";" MySQL said: #1065 - Query was empty
Here's the new trigger (AFTER INSERT):
BEGIN
DECLARE vIdPlacet VARCHAR(40);
DECLARE vTypeTravaux VARCHAR(32);
DECLARE vEssence VARCHAR(3) DEFAULT '-';
DECLARE vClasseHau VARCHAR(5) DEFAULT '-';
DECLARE vNoMesurag int;
DECLARE new_id_parcelle INT UNSIGNED DEFAULT 0;
DECLARE new_no_microplacette INT UNSIGNED DEFAULT 0;
IF NEW.deleted = 0 THEN
SELECT id_parcelle, no_microplacette
INTO new_id_parcelle, new_no_microplacette
FROM microplacette
WHERE id_microplacette = NEW.id_microplacette;
SELECT travaux, no_mesurag, id__placet
INTO vTypeTravaux, vNoMesurag, vIdPlacet
FROM secteur
LEFT JOIN parcelle ON secteur.id_secteur = parcelle.id_secteur
WHERE id_parcelle = new_id_parcelle;
IF vTypeTravaux = 'inventaire' THEN
SELECT abbreviation INTO vEssence FROM essences WHERE _id = NEW.id_essence;
IF NEW.hauteur_15 = 1 THEN
SET vClasseHau = '15CM+';
END IF;
IF (SELECT COUNT(*) FROM imported_pres_ess WHERE id__placet = vIdPlacet AND
caracteris = '-' AND
classe_hau = vClasseHau AND
essence = vEssence AND
no_mesurag = vNoMesurag AND
no_micro_p = new_no_microplacette) = 0 THEN
INSERT INTO imported_pres_ess (id__placet, caracteris, classe_hau, essence, no_mesurag, no_micro_p)
VALUES (vIdPlacet, '-', vClasseHau, vEssence, vNoMesurag, new_no_microplacette);
END IF;
IF (SELECT COUNT(*) FROM imported_semi_gau WHERE id__placet = vIdPlacet AND
classe_hau = vClasseHau AND
essence = vEssence AND
no_mesurag = vNoMesurag AND
no_micro_p = new_no_microplacette) = 0 THEN
INSERT INTO imported_semi_gau (id__placet, classe_hau, essence, no_mesurag, no_micro_p)
VALUES (vIdPlacet, vClasseHau, vEssence, vNoMesurag, new_no_microplacette);
END IF;
IF NEW.diametre > 0 THEN
SET vClasseHau = 'D2_D8';
ELSE
SET vClasseHau = '-';
END IF;
IF (SELECT COUNT(*) FROM imported_pres_ess WHERE id__placet = vIdPlacet AND
caracteris = '-' AND
classe_hau = vClasseHau AND
essence = vEssence AND
no_mesurag = vNoMesurag AND
no_micro_p = new_no_microplacette) = 0 THEN
INSERT INTO imported_pres_ess (id__placet, caracteris, classe_hau, essence, no_mesurag, no_micro_p)
VALUES (vIdPlacet, '-', vClasseHau, vEssence, vNoMesurag, new_no_microplacette);
END IF;
IF (SELECT COUNT(*) FROM imported_semi_gau WHERE id__placet = vIdPlacet AND
classe_hau = vClasseHau AND
essence = vEssence AND
no_mesurag = vNoMesurag AND
no_micro_p = new_no_microplacette) = 0 THEN
INSERT INTO imported_semi_gau (id__placet, classe_hau, essence, no_mesurag, no_micro_p)
VALUES (vIdPlacet, vClasseHau, vEssence, vNoMesurag, new_no_microplacette);
END IF;
END IF;
END IF;
END
I tried creating the procedure you show, but I don't get any error.
The error about "empty statement" happens when you try to execute a query through the API but the query string is empty.
I can duplicate the error in the mysql client this way:
mysql> set #s = '';
mysql> prepare stmt from #s;
ERROR 1065 (42000): Query was empty
So I suggest you look not at the stored procedure, but whatever code you're executing this from, and check that every time you try to execute a query, that you submit a non-empty string.
It turns out, the trigger I was updating got deleted in the meantime, so I was updating a trigger that didn't exist anymore.
I found out after refreshing the page (the trigger was gone from the trigger list).
I simply recreated the trigger anew and it worked.

update query in MYSQL stored procedure

When I execute below update query in mysql workbench It will update only 2 rows.
UPDATE usertoken
SET StatusName='Completed',Id=null
WHERE (UserId=45 and BuddyId=46) OR (UserId=46 and BuddyId=45);
but the same query inside the Stored Procedure updates the entire table.
Even I hard coded the user id's inside the Stored procedure nothing changed.
Any Idea's?
UPDATE:
CREATE DEFINER=`root`#`%` PROCEDURE `SubmitResult`(IN userId int,IN buddyID int,IN startTime DATETIME,IN endtime DATETIME,IN questions varchar(255),IN answers varchar(255))
BEGIN
SET #userId = userId;
SET #questions = questions;
SET #answers = answers;
SET #buddyID = buddyID;
SELECT #QuizId := QuizId from usertoken where (UserId=#userId and BuddyId=#buddyID) OR (UserId=#buddyID and BuddyId=#userId) LIMIT 1;
IF #QuizId IS NULL THEN
INSERT INTO QUIZ (QuizStartTime, QuizEndTime, QuizTypeId)
SELECT startTime,endtime,1;
SELECT #newQId := MAX(QuizId) from QUIZ LIMIT 1;
SELECT #userId,#buddyID,#newQId;
/* UPDATE usertoken SET QuizStatusName='Completed',QuizId=#newQId where (UserId=#userId and BuddyId=#buddyID) OR (UserId=#buddyID and BuddyId=#userId); */
UPDATE usertoken SET QuizStatusName='Completed',QuizId=#newQId where UserId=45;
UPDATE usertoken SET QuizStatusName='Completed',QuizId=#newQId where UserId=46;
// Some Statements
END IF;
SET #userId = NULL;
SET #questions = NULL;
SET #answers = NULL;
SET #buddyID = NULL;
SET #startTime = NULL;
SET #endtime = NULL;
SET #QID = NULL;
SET #AID = NULL;
SET #n = NULL;
SET #newQMId = NULL;
SET #newQId = NULL;
SET #QuizId = NULL;
END
My update query works well after prefixing the where condition with table alias name.. Not sure why it got failed but i assume that Stored procedure IN parameter has the same userId attribute and it could be cause..
After prefixing my update query,
UPDATE usertoken t
SET t.StatusName='Completed',t.Id=null
WHERE (t.UserId=45 and t.BuddyId=46) OR (t.UserId=46 and t.BuddyId=45);

MySQL script error

I'm new to SQL programming and I decided to make a script. This one might be quite riddled with errors but I'm getting an error that I'm unable to resolve.
DELIMITER $
DROP FUNCTION IF EXISTS crossref$
CREATE FUNCTION crossref()
BEGIN
DECLARE i INT;
DECLARE names VARCHAR(70);
SET i = 1;
myloop: LOOP
SET i=i+1;
IF i = 6 then
LEAVE myloop;
END IF;
SET names = (SELECT NAME FROM cbase_excel_table WHERE ID = i);
INSERT INTO cbase_master(NAME, PERMALINK, HOMEPAGE_URL, CATEGORY_LIST, MARKET, FUNDING, 'STATUS', COUNTRY, REGION, CITY)
SELECT NAME, PERMALINK, HOMEPAGE_URL, CATEGORY_LIST, MARKET, FUNDING, 'STATUS', COUNTRY, REGION, CITY FROM cbase_excel_table WHERE ID = i;
UPDATE cbase_master
SET DESCRIPTION = (SELECT DESCRIPTION FROM cbase_json_table WHERE NAME = names)
SET DOMAIN = (SELECT DOMAIN FROM cbase_json_table WHERE NAME = names)
SET IMAGE_URL = (SELECT IMAGE_URL FROM cbase_json_table WHERE NAME = names)
SET FACEBOOK_URL = (SELECT FACEBOOK_URL FROM cbase_json_table WHERE NAME = names)
SET TWITTER_URL = (SELECT TWITTER_URL FROM cbase_json_table WHERE NAME = names)
SET LINKEDIN_URL = (SELECT LINKEDIN_URL FROM cbase_json_table WHERE NAME = names)
SET CBASE_UUID = (SELECT CBASE_UUID FROM cbase_json_table WHERE NAME = names);
END LOOP myloop;
END$
DELIMITER;
and I'm getting:
#1064 - 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
DECLARE i INT;
DECLARE names VARCHAR(70);
SET i = 1;
Any help?
An example of a function which shows a major difference to your function:
CREATE FUNCTION `fnFindMaximum`(`a` INT, `b` INT)
/* Before the BEGIN statement there are other things going on - the most important being the return type statement */
RETURNS int(11)
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE returnval INTEGER;
IF a >= b THEN
SET returnval = a;
ELSE
SET returnval = b;
END IF;
RETURN returnval;
END
Your function then goes on to manipulate sql but does not return a value so, as was pointed out by #arkhil, use a StoredProcedure in preference to a function.

MySQL Trigger - Where am I going wrong

Can someone tell me where I'm going wrong in creating this trigger in MySQL? Every time I try to create it, it keeps telling me there is an error.
USE `cl11-onestock`;
DELIMITER //
CREATE TRIGGER audit_insert
AFTER INSERT
ON stock_usage FOR EACH ROW
BEGIN
SET uUid = (SELECT UUID());
SET stockUsageId = (SELECT NEW.stock_usage_id);
SET siteId = (SELECT NEW.site_id);
SET date = (SELECT NEW.date);
SET patientName = (SELECT NEW.patient_name);
SET dentistDiscountId = (SELECT NEW.dentist_discount_id);
SET itemId = (SELECT NEW.item_id);
SET quantity = (SELECT NEW.quantity);
SET priceIncDiscount = (SELECT NEW.price_inc_discount);
SET vat = (SELECT NEW.vat);
SET priceIncVat = (SELECT NEW.price_inc_vat);
SET createdAt = (SELECT NEW.created_at);
SET updatedAt = (SELECT NEW.updated_at);
INSERT INTO stock_audit VALUES
(uUid, stockUsageId, siteId, date, patientName, dentistDiscountId, itemId, quantity, priceIncDiscount, vat, priceIncVat, createdAt, updatedAt);
END; //
DELIMITER ;
You need to use the keyword new to access the field values after insert and not like you are doing with select and you can use directly inside the insert query
So the trigger should be as
DELIMITER //
CREATE TRIGGER audit_insert
AFTER INSERT
ON stock_usage FOR EACH ROW
BEGIN
INSERT INTO stock_audit VALUES
(new.UUID, NEW.stock_usage_id, NEW.site_id, NEW.date, NEW.patient_name, NEW.dentist_discount_id, NEW.item_id, NEW.quantity, NEW.price_inc_discount, NEW.vat, NEW.price_inc_vat, NEW.created_at, NEW.updated_at);
END; //
DELIMITER ;