What does "The following query failed" ";"" mean in MySQL? - 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.

Related

mySql procedure condition does not occur

I have the following stored procedure in MySql..
main: BEGIN
DECLARE user_name VARCHAR(65);
DECLARE home_path VARCHAR(255);
DECLARE home_perm VARCHAR(10);
DECLARE num_posts, param_index INT(10);
SELECT `account`, `Posts`
INTO user_name, num_posts
FROM account_info
WHERE account = username_in AND password = password_in;
IF (user_name = NULL) OR (user_name != username_in) THEN
LEAVE main;
END IF;
SET home_perm = 'LRS';
IF num_posts > 100 THEN
SET param_index = 1;
SET home_path = 'c:\\folder_1';
ELSEIF num_posts > 200 THEN
SET param_index = 2;
SET home_path = 'c:\\folder_2';
ELSE
SET param_index = 0;
SET home_path = 'c:\\folder_0';
END IF;
SELECT home_path,home_perm,param_index;
END
When I test this procedure with a username that is incorrect I want it to "LEAVE main" but even if I do that it still does not enter LEAVE main, what can I do to fix this?
null value does not equal to anything, therefore both comparisons will return false. Use either the is null operator, or <=> operator to compare a variable with null.
user_name IS NULL

MySQL IN Clause in SQL query with User Defined Function

I am using following query to update all the children of particular topic.
UPDATE topics SET reuse = 0 WHERE topic_id IN (SELECT GetChildTopics(187));
Where
SELECT GetChildTopics(187);
returns "188,190,189" but my update query is updating only first row with topic_id = 188, instead of updating first topic only, it should update all 3 topics.
When I put the values manually it works fine.
UPDATE topics SET reuse = 0 WHERE topic_id IN (188,190,189);
Can anyone suggest what's wrong I am doing here?
Here is the code for GetChildTopics MySQL Function
CREATE DEFINER=`root`#`localhost` FUNCTION `GetAncestry`(GivenID INT) RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE rv VARCHAR(1024);
DECLARE cm CHAR(1);
DECLARE ch INT;
SET rv = '';
SET cm = '';
SET ch = GivenID;
WHILE ch > 0 DO
SELECT IFNULL(parent_topic_id,-1) INTO ch FROM
(SELECT parent_topic_id FROM topic_list WHERE id = ch) A;
IF ch > 0 THEN
SET rv = CONCAT(rv,cm,ch);
SET cm = ',';
END IF;
END WHILE;
RETURN rv;
END
Try this;)
UPDATE topics SET reuse = 0 WHERE FIND_IN_SET(topic_id, GetChildTopics(187));

Declaring a variable in mysql trigger

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$$

Asking about stored function in mysql

drop function if exists rty_check_member_info_status;
DELIMITER $$
--
-- Functions
CREATE DEFINER=root#localhost FUNCTION rty_check_member_info_status(memb_id int,field_name_1 varchar(100),field_name_2 varchar(100),login_member_amount int(11),login_status char(1)) RETURNS char(1) CHARSET latin1
begin
declare fn_field_name_1 varchar(100) ;
declare fn_field_name_2 varchar(100) ;
declare fn_amount_for_profile_visible int(11);
declare fn_return char(1) default 'N';
declare test_field varchar(100);
select field_name_1,field_name_2,amount_for_profile_visible into
fn_field_name_1,fn_field_name_2,fn_amount_for_profile_visible
from member_account_settings inner join tbl_members on member_account_settings.member_auto_id = tbl_members.member_id
where tbl_members.member_id = memb_id ;
if fn_field_name_1 = 'H' Then
set fn_return = 'N' ;
else
if fn_field_name_2 = 'Y' Then
if fn_amount_for_profile_visible = '0' Then
set fn_return = 'Y' ;
else
if login_status = 1 Then
if fn_amount_for_profile_visible > login_member_amount Then
set fn_return = 'N' ;
else
set fn_return = 'Y' ;
end if;
else
set fn_return = 'N';
end if ;
end if;
else
set fn_return = 'Y';
end if ;
end if ;
return fn_return ;
end$$
DELIMITER ;
You're two choices are pretty much generated SQL(normally a bad idea because it's harder to write, debug and document) and using a case statement to select the column based on the name matching a string(which is normally a pretty good solution).
Here's an example of the second, since it's the solution I'd definitely recommend.
SET #test_field1 = "last_name_display_status" ;
SET #test_field2 = "last_name_display_for_other_partcpnt" ;
SELECT
CASE #test_field1
-- List columns here that you might want to return:
WHEN 'last_name_display_status' THEN last_name_display_status
WHEN 'last_name_display_for_other_partcpnt' THEN last_name_display_for_other_partcpnt
WHEN 'create_date' THEN create_date
-- Return a value for an invalid name here:
ELSE NULL
END AS test_field1,
CASE #test_field2
-- List columns here that you might want to return:
WHEN 'last_name_display_status' THEN last_name_display_status
WHEN 'last_name_display_for_other_partcpnt' THEN last_name_display_for_other_partcpnt
WHEN 'create_date' THEN create_date
-- Return a value for an invalid name here:
ELSE NULL
END AS test_field2,
-- Rest of select unaffected by this change
amount_for_profile_visible
INTO
fn_field_name_1,
fn_field_name_2,
fn_amount_for_profile_visible
FROM member_account_settings
INNER JOIN tbl_members
ON member_account_settings.member_auto_id = tbl_members.member_id
WHERE
tbl_members.member_id = memb_id
;
And for the sake of completeness a copy of the first solution I proposed(the generated SQL):
-- Need to use #vars, since named vars aren't in scope for the generated SQL:
SET #output1 = '';
SET #output2 = '';
SET #output3 = '';
SET #input1 = memb_id;
-- We also need to store our generated SQL to a variable
SET #query = 'SELECT ' + #test_field1 + ',' + #test_field2 + ', amount_for_profile_visible INTO #output1, #output2, #output3 FROM member_account_settings INNER JOIN tbl_members ON member_account_settings.member_auto_id = tbl_members.member_id WHERE tbl_members.member_id = ?';
-- To execute the code we have to convert it to a prepared statement
-- named stmt here, because it's what most people use in this instance
PREPARE stmt FROM #query;
-- Execute the statement using our input variable
EXECUTE stmt USING #input1;
-- Delete the prepared statement now we've run it.
DEALLOCATE PREPARE stmt;
-- Store our #vars back into the named vars.
SET fn_field_name_1 = #output1;
SET fn_field_name_2 = #output2;
SET fn_amount_for_profile_visible = #output3;

mysql stored procedure error (1172, 'Result consisted of more than one row')

When trying to run the following stored procedure from django, I get an OperationError (1172, 'Result consisted of more than one row') Any idea what I might be doing wrong?
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `UpdatePrices`(IN storeId int, IN bottleSize VARCHAR(50))
BEGIN
DECLARE amount DECIMAL(10,2); DECLARE isCustom INT DEFAULT 0;
DECLARE changeType VARCHAR(50) DEFAULT 'State'; DECLARE updateType INT DEFAULT 0;
IF bottleSize = '1000 Ml' THEN
SELECT S1000IncreaseChoices INTO changeType FROM store_store WHERE StoreID = storeId;
IF changeType = 'State' THEN
SELECT updateType = 0;
END IF;
IF changeType = 'Flat' THEN
SELECT S1000IncreaseAmount INTO amount FROM store_store WHERE StoreID = storeId;
SELECT updateType = 1;
END IF;
IF changeType = 'Percent' THEN
SELECT 1 - S1000IncreaseAmount/100 INTO amount FROM store_store WHERE StoreID = storeId;
SELECT updateType = 2;
END IF;
END IF;
IF updateType = 0 THEN
update store_storeliquor SL
inner join liquor_liquor LL
on liquorID_id = id
set StorePrice = ShelfPrice
where BottleSize = bottleSize
and storeID_id = storeId
and custom = 0;
END IF;
IF updateType = 1 THEN
update store_storeliquor SL
inner join liquor_liquor LL
on liquorID_id = id
set StorePrice = OffPremisePrice + amount
where BottleSize = bottleSize
and storeID_id = storeId
and custom = 0;
END IF;
IF updateType = 1 THEN
update store_storeliquor SL
inner join liquor_liquor LL
on liquorID_id = id
set StorePrice = OffPremisePrice / amount
where BottleSize = bottleSize
and storeID_id = storeId
and custom = 0;
END IF;
END
I'm not sure if it matters, but I initiate the stored procedure like so:
def priceupdate(request, store_id):
cursor = connection.cursor()
cursor.callproc("UpdatePrices", (store_id, '1000 ML'))
cursor.close()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Your SELECT...INTO queries give result sets with more then one record. The WHERE filters are incorrect - they compare two the same values StoreID = storeId. Rename IN storeId int parementer to another name. For example - IN storeId_param int
The query will be like this -
SELECT S1000IncreaseChoices INTO changeType FROM store_store WHERE StoreID = storeId_param;
This is a Bug and you need to apply something like that:
SELECT id,data INTO x,y FROM test.t1 LIMIT 1;