Stored procedure not working properly via EXECUTE - mysql

I have the following stored procedure but it's not working properly. if call the procedure it gives a correct value but not updated the next value.
DROP procedure IF EXISTS `GetCommonSequenceReferenceData`;
CREATE PROCEDURE `GetCommonSequenceReferenceData`(
IN refData JSON
)
BEGIN
DECLARE sequ_id BIGINT;
DECLARE sequ_next_id BIGINT;
SELECT *
FROM COMMON_SEQ_REF_TB
WHERE seq_type = refData ->> "$.seq_type";
SET sequ_id = (SELECT seq_id
FROM COMMON_SEQ_REF_TB
WHERE seq_type = refData ->> "$.seq_type");
SET sequ_next_id = (SELECT next_id
FROM COMMON_SEQ_REF_TB
WHERE seq_type = refData ->> "$.seq_type");
IF (sequ_id IS NULL) THEN
SET sequ_next_id = 1;
INSERT INTO COMMON_SEQ_REF_TB (seq_type, next_id, created_at, updated_at)
VALUES (refData ->> "$.seq_type", sequ_next_id,
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP());
ELSE
SET sequ_next_id = sequ_next_id + 1;
-- UPDATE START
UPDATE COMMON_SEQ_REF_TB
SET next_id = sequ_next_id,
updated_at = CURRENT_TIMESTAMP()
WHERE seq_type = refData ->> "$.seq_type";
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.

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;

Mysql WHERE IN (*)

I have a procedure A which takes an array of strings. By calling another procedure B, i break this array in this format:
'1','2','3','4'
In case there is only one value, it just displays as '1'
I want to return * in case the array passed to the procedure A.
Therefore, my query will be like this: select * from users where userId(*);
What i want is that in case the parameter is null, it should still perform the IN using.
** EDIT **
Nothing much of query
CREATE DEFINER=`root`#`localhost` PROCEDURE `listAll`(IN id varchar(200))
BEGIN
set #t = lib_explode(',',id);
select * from city where ID in(#t);
END
Procedure B
CREATE DEFINER=`root`#`localhost` FUNCTION `lib_explode`(sSepar VARCHAR(255), saVal TEXT) RETURNS varchar(200) CHARSET utf8
body:
BEGIN
IF sSepar IS NULL OR saVal IS NULL THEN LEAVE body; END IF;
SET #saTail = saVal;
SET #iSeparLen = LENGTH( sSepar );
set #mystring = '';
set #current_pos = 1;
create_layers:
WHILE #saTail != '' DO
# Get the next value
SET #sHead = SUBSTRING_INDEX(#saTail, sSepar, 1);
SET #saTail = SUBSTRING( #saTail, LENGTH(#sHead) + 1 + #iSeparLen );
-- INSERT INTO lib_Explode SET val = #sHead;
if(#current_pos > 1) then
set #mystring = concat(#mystring,',',concat("'",#shead,"'"));
else
set #mystring = concat(#mystring,concat("'",#shead,"'"));
end if;
set #current_pos = #current_pos + 1;
END WHILE;
return #mystring;
END

Mysql cursor fetches only first row

Mysql cursor fetches only first row and when it has fetched the second row the row_not_found variable is set to false and cursor close.
Please look into below SP:
CREATE DEFINER = 'root'#'localhost'
PROCEDURE billingv2test.SP_CreateRecurringBillingOrders(IN _billingDate DATETIME,
IN _defaultBillingFrequency INT,
IN _IsForcedExecution BIT)
BEGIN
DECLARE _userId char(36);
DECLARE _billingStartDate datetime;
DECLARE _billingEndDate datetime;
DECLARE _cmd VARCHAR(4000);
DECLARE _userBillingHistoryId char(36);
DECLARE _paymentOrderId char(36);
DECLARE _orderNumber VARCHAR(100);
DECLARE _totalChargeAmount DECIMAL(15, 6);
DECLARE _couponChargeAmount DECIMAL(15, 6);
DECLARE _pendingChargeAmount DECIMAL(15, 6);
DECLARE _isError BIT;
DECLARE _noOfUsersProcessed BIT;
DECLARE _billingResourceType VARCHAR(20);
DECLARE _RowNo INT;
DECLARE _defaultDateTime DATETIME;
DECLARE record_not_found INTEGER DEFAULT 0;
DECLARE user_list varchar(200);
DECLARE ProcessUsersForRecurringBilling_Cursor CURSOR FOR
SELECT OwnerId FROM UserBillingInfo
WHERE NextBillingDate IS NOT NULL
AND cast(NextBillingDate as date) <= cast( _billingDate as date)
AND IsProcessPending = 0
AND IsDeleted = 0
AND BillingStatus <> 'Delinquent'
ORDER BY NextBillingDate;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET record_not_found = 1;
SET _isError = 0;
SET _noOfUsersProcessed = 0;
SET _defaultDateTime = '1900-01-01 00:00:00';
SET _userBillingHistoryId = UUID();
INSERT INTO BillingHistory( Id, BillingStartTime, BillingEndTime, Status, NoOfUsersProcessed, CreateTime, UpdateTime )
VALUES ( _userBillingHistoryId, UTC_TIMESTAMP(), NULL , 'Started', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP());
OPEN ProcessUsersForRecurringBilling_Cursor;
allusers: LOOP
FETCH ProcessUsersForRecurringBilling_Cursor INTO _userId;
IF record_not_found THEN
LEAVE allusers;
END IF;
SET user_list = CONCAT(IFNULL(user_list,''),", ",_userId);
SET _isError = 0;
SET _orderNumber = '';
SET _totalChargeAmount = '0';
SET _couponChargeAmount = '0';
SET _pendingChargeAmount = '0';
UPDATE UserBillingInfo SET IsProcessPending = 1 WHERE OwnerId = _userId;
SET _billingStartDate = _defaultDateTime;
SELECT
IFNULL(InvoiceDate, _defaultDateTime) INTO _billingStartDate
FROM
PaymentOrder
WHERE OwnerId = _userId AND OrderStatus IN ('Success', 'Submitted')
ORDER BY CreateTime DESC
LIMIT 1;
SELECT NextBillingDate INTO _billingEndDate FROM UserBillingInfo WHERE OwnerId = _userId;
SET _orderNumber = UUID();
SET _orderNumber = SUBSTRING(_orderNumber, 0, LOCATE('-', _orderNumber));
-- CALL SP_CreateRecurringBillingPaymentOrder
CALL SP_CreateRecurringBillingPaymentOrder
(_userId, _billingStartDate, _billingEndDate, _orderNumber, _userBillingHistoryId, _paymentOrderId);
SELECT Amount INTO _totalChargeAmount FROM PaymentOrder WHERE Id = _paymentOrderId;
SET _pendingChargeAmount = _totalChargeAmount;
UPDATE PaymentOrder set ChargeAmount = _pendingChargeAmount, UpdateTime = UTC_TIMESTAMP()
WHERE Id = _paymentOrderId;
UPDATE ResourceUsageProcessed SET BillingStatus = 'Completed'
WHERE PaymentOrderId = _paymentOrderId AND BillingStatus = 'Processing';
SET _noOfUsersProcessed = _noOfUsersProcessed + 1;
END LOOP allusers;
CLOSE ProcessUsersForRecurringBilling_Cursor;
UPDATE BillingHistory SET NoOfUsersProcessed = _noOfUsersProcessed, Status = 'Completed', BillingEndTime = UTC_TIMESTAMP()
WHERE Id = _userBillingHistoryId;
END
hey this may sound silly but try this
IF record_not_found=1 THEN
LEAVE allusers;