SQL Error: No data - zero rows fetched, selected, or processed - mysql

CREATE PROCEDURE KC_update_pricing()
BEGIN
DECLARE u_sku VARCHAR(10) DEFAULT "";
DECLARE u_product_size VARCHAR(4) DEFAULT "";
DECLARE u_product_name VARCHAR(100) DEFAULT "";
DECLARE u_chargeble_area DECIMAL DEFAULT 0.0;
DECLARE u_user_id VARCHAR(10) DEFAULT "";
DECLARE u_last_update DATE;
DECLARE cur1 CURSOR FOR
SELECT
sku,
product_size,
product_name,
chargeble_area,
user_id,
last_update
FROM kcproduct_test_load
WHERE last_update >= (SELECT DATE_FORMAT(DATE_SUB(max(last_update), INTERVAL 1 DAY), '%d-%m-%Y')
FROM kcpricing_test_load);
OPEN Cur1;
LOOP
FETCH cur1
INTO u_sku, u_product_size, u_product_name, u_chargeble_area, u_user_id, u_last_update;
IF (u_product_size = 'S')
THEN
SET u_shipping = 99;
ELSEIF (u_product_size = 'M')
THEN
SET u_shipping = 149;
ELSEIF (u_product_size = 'L')
THEN
SET u_shipping = 199;
ELSEIF (u_product_size = 'XS')
THEN
SET u_shipping = 99;
ELSEIF (u_product_size = 'XXS')
THEN
SET u_shipping = 69;
ELSE
SET u_shipping = 199;
END IF;
UPDATE kcpricing_test_load
SET base_price = (u_chargeble_area * 150)
WHERE sku = u_SKU;
END LOOP;
END;

have an exception command in the cursor some thing like below :
Exception
When NO_DATA_FOUND then
continue
end;
it will help to avoid no data found error.

Related

How do I fetch the data using multiple cursors and multiple loops in MySQL Stored Procedure?

As per the use case, this procedure should return 30 rows with 15 unique lead id's corresponding to all 15 in activity=1; randomly 10 participate in activity = 2; and from those 10, 5 leads randomly correspond to activity=3.
When I run the stored procedure, it goes on until populating 25 records; which correspond to uniquely getting 15 id's for activity=1 and 10 out of them for activity=2; but, I am unable to fetch the records right after.
If you check down in the code; I have mentioned a SELECT statement just before closing cur2 (SELECT COUNT(*) FROM task2), which should return Count=25; but it's not. So, apparently, the program isn't even going further into the cur3 which I have declared for activity=3.
I have tried using Continue Handler with cursor, too; but it didn't seem to work!
Can anyone help resolve this issue?
BEGIN
DROP TABLE IF EXISTS task2;
CREATE TABLE task2 (
ID int(11) NOT NULL AUTO_INCREMENT,
type_id int(11) DEFAULT NULL,
url varchar(100) DEFAULT NULL,
lead_id int(11) DEFAULT NULL,
createdDate datetime DEFAULT NULL,
month varchar(20) DEFAULT NULL,
year int(11) DEFAULT NULL,
month_year varchar(20) DEFAULT NULL,
PRIMARY KEY (ID)
)
BEGIN
-- INSERTING DATA FOR ACTIVITY = 1
DECLARE nurl VARCHAR(100);
DECLARE nleadid INTEGER;
DECLARE ncreateddate DATETIME;
DECLARE l_count INTEGER;
DECLARE loop_count INTEGER;
-- LOOP COUNT = 15
SET l_count = 15;
SET loop_count = 1;
read_loop:LOOP
IF loop_count > l_count THEN
LEAVE read_loop;
END IF;
IF loop_count = 1
THEN
SET nleadid = 100;
SET ncreateddate = ('2012-09-08 01:09:30');
ELSE
SET nleadid = 100 + loop_count - 1;
SET ncreateddate = (SELECT MAX(createdDate) FROM task2);
SET ncreateddate = DATE_ADD(ncreateddate, INTERVAL ELT(0.5 + RAND() * 6, '3', '5', '45', '34', '23', '68') MINUTE);
END IF;
SET nurl = ELT(0.5 + RAND() * 3, 'g.com', 'y.com', 'm.com');
INSERT INTO task2 (type_id, url, lead_id, createdDate)
VALUES ('1', nurl, nleadid, ncreateddate);
UPDATE task2
SET month = MONTHNAME(createddate), year = YEAR(createddate), month_year = CONCAT(MONTHNAME(createddate),'-', YEAR(createddate));
SET loop_count = loop_count + 1;
END LOOP read_loop;
END;
-- INSERTING THE DATA FOR ACTIVITY = 2
BEGIN
DECLARE nurl VARCHAR(100);
DECLARE nleadid INTEGER;
DECLARE ncreateddate DATETIME;
DECLARE l_count INTEGER;
DECLARE loop_count INTEGER;
-- CURSOR DECLARATION TO FETCH 10 RANDOM RECORDS FROM ACTIVITY=1
DECLARE cur2 CURSOR FOR
SELECT DISTINCT lead_id FROM task2 WHERE type_id = 1 ORDER BY RAND() LIMIT 10;
SET l_count = 10;
SET loop_count = 1;
OPEN cur2;
read_loop:LOOP
FETCH cur2 INTO nleadid;
IF loop_count > l_count THEN
SELECT loop_count_2, l_count_2;
LEAVE read_loop;
END IF;
SET nurl = ELT(0.5 + RAND() * 3, 'g.com', 'y.com', 'm.com');
SET ncreateddate = (SELECT MAX(createdDate) FROM task2 WHERE lead_id = nleadid);
SET ncreateddate = DATE_ADD(ncreateddate, INTERVAL ELT(0.5 + RAND() * 6, '3', '5', '45', '34', '23', '68') MINUTE);
INSERT INTO task2 (type_id, url, lead_id, createdDate)
VALUES ('2', nurl, nleadid, ncreateddate);
UPDATE task2
SET month = MONTHNAME(createddate), year = YEAR(createddate), month_year = CONCAT(MONTHNAME(createddate),'-', YEAR(createddate));
SET loop_count = loop_count + 1;
SELECT COUNT(*) FROM task2;
END LOOP read_loop;
SELECT COUNT(*) FROM task2;
CLOSE cur2;
END;
-- INSERTING DATA FOR ACTIVITY = 3
BEGIN
DECLARE nurl VARCHAR(100);
DECLARE nleadid INTEGER;
DECLARE ncreateddate DATETIME;
DECLARE l_count INTEGER;
DECLARE loop_count INTEGER;
-- CURSOR DECLARATION FOR SELECTING 5 RANDOM LEADS FROM ACTIVITY=2
DECLARE cur3 CURSOR FOR
SELECT DISTINCT lead_id FROM task2 WHERE type_id = 2 ORDER BY RAND() LIMIT 5;
SET l_count = 5;
SET loop_count = 1;
OPEN cur3;
read_loop:LOOP
IF loop_count > l_count THEN
LEAVE read_loop;
END IF;
FETCH cur3 INTO nleadid;
SET nurl = CONCAT(ELT(0.5 + RAND() * 3, 'g.com', 'y.com', 'm.com'), ELT(0.5 + RAND() * 3, '/home.html', '/index.html', '/about.html'));
SELECT nurl;
SET ncreateddate = (SELECT MAX(createdDate) FROM task2 WHERE lead_id = nleadid);
SET ncreateddate = DATE_ADD(ncreateddate, INTERVAL ELT(0.5 + RAND() * 6, '3', '5', '45', '34', '23', '68') MINUTE);
SELECT ncreateddate;
INSERT INTO task2 (type_id, url, lead_id, createdDate)
VALUES ('3', nurl, nleadid, ncreateddate);
UPDATE task2
SET month = MONTHNAME(createddate), year = YEAR(createddate), month_year = CONCAT(MONTHNAME(createddate),'-',YEAR(createddate));
SET loop_count =loop_count + 1;
END LOOP read_loop;
CLOSE cur3;
END;
SELECT * FROM task2;
END

MySQL store procedure Assign value to multiple variable from select statement

This is my Stored procedure . I have problem to assign value to Declared variable . When I Execute it, Insert and Update Command work fine but VALUE of Declared Variable remain 0; But I have some value in Database. How can i Do this Corectly.
BEGIN
DECLARE PaidFee INT DEFAULT 0;
DECLARE DueFee INT DEFAULT 0;
DECLARE CourseFee INT DEFAULT 0;
INSERT INTO `creditdirectory`(`TypeID`, `PersonName`, `CreditBy`, `PersonID`, `ModeOfPayment`,`Details`,`Amount`,`CompanyID`)
VALUES(1,PersonName,CreditBy, AddmissionID, ModeOfPayment, 'Installment', PaidAmount,
CompanyID);
SELECT `CourseFee`,`PaidFee`,`DueFee` INTO CourseFee,PaidFee,DueFee FROM `studentcoursedetails` WHERE `ID`= CourseID;
SET PaidFee = PaidFee + PaidAmount;
SET DueFee = CourseFee - PaidFee;
IF (NextDueDate !='') THEN
UPDATE `studentcoursedetails` SET `PaidFee` = PaidFee, `DueFee` = DueFee, `DueDate` = NextDueDate WHERE `ID`= CourseID;
ELSE
UPDATE `studentcoursedetails` SET `PaidFee` = PaidFee, `DueFee` = DueFee, `DueDate` = NULL WHERE `ID` = CourseID;
END IF;
END
Don't use variables with same name of columns, the query will take preference on table column names.
A good idea is use variables with prefix:
BEGIN
DECLARE p_PaidFee INT DEFAULT 0;
DECLARE p_DueFee INT DEFAULT 0;
DECLARE p_CourseFee INT DEFAULT 0;
INSERT INTO `creditdirectory`(`TypeID`, `PersonName`, `CreditBy`, `PersonID`, `ModeOfPayment`,`Details`,`Amount`,`CompanyID`)
VALUES(1,PersonName,CreditBy, AddmissionID, ModeOfPayment, 'Installment', PaidAmount,
CompanyID);
SELECT `CourseFee`,`PaidFee`,`DueFee` INTO p_CourseFee,p_PaidFee,p_DueFee FROM `studentcoursedetails` WHERE `ID`= CourseID;
SET p_PaidFee = p_PaidFee + PaidAmount;
SET p_DueFee = p_CourseFee - p_PaidFee;
IF (NextDueDate !='') THEN
UPDATE `studentcoursedetails` SET `PaidFee` = p_PaidFee, `DueFee` = p_DueFee, `DueDate` = NextDueDate WHERE `ID`= CourseID;
ELSE
UPDATE `studentcoursedetails` SET `PaidFee` = p_PaidFee, `DueFee` = p_DueFee, `DueDate` = NULL WHERE `ID` = CourseID;
END IF;
END

How to get only Digits from String in mysql?

I have some string output which contain alphanumeric value. I want to get only Digits from that string. how can I fetch this by query? which MySql function can I Use?
My query is like :
select DISTINCT SUBSTRING(referrerURL,71,6)
from hotshotsdblog1.annonymoustracking
where advertiserid = 10
limit 10;
Output :
100683
101313
19924&
9072&h
12368&
5888&h
10308&
100664
1&hash
101104
And I Want output like :
100683
101313
19924
9072
12368
5888
10308
100664
1
101104
If the string starts with a number, then contains non-numeric characters, you can use the CAST() function or convert it to a numeric implicitly by adding a 0:
SELECT CAST('1234abc' AS UNSIGNED); -- 1234
SELECT '1234abc'+0; -- 1234
To extract numbers out of an arbitrary string you could add a custom function like this:
DELIMITER $$
CREATE FUNCTION `ExtractNumber`(in_string VARCHAR(50))
RETURNS INT
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(50);
DECLARE finNumber VARCHAR(50) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti INTEGER DEFAULT 1;
IF LENGTH(in_string) > 0 THEN
WHILE(inti <= LENGTH(in_string)) DO
SET sChar = SUBSTRING(in_string, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finNumber = CONCAT(finNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
RETURN CAST(finNumber AS UNSIGNED);
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
Once the function is defined, you can use it in your query:
SELECT ExtractNumber("abc1234def") AS number; -- 1234
To whoever is still looking, use regex:
select REGEXP_SUBSTR(name,"[0-9]+") as amount from `subscriptions`
Here I got success with this function:
select REGEXP_REPLACE('abc12.34.56-ghj^-_~##!', '[^0-9]+', '')
output: 123456
Explaining: basically I'm asking for mysql replace all 'not numbers' in interval from 0 to 9 to ''.
Based on Eugene Yarmash Answer. Here is a version of the custom function that extracts a decimal with two decimal places. Good for price extraction.
DELIMITER $$
CREATE FUNCTION `ExtractDecimal`(in_string VARCHAR(255))
RETURNS decimal(15,2)
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(255);
DECLARE in_string_parsed VARCHAR(255);
DECLARE digitsAndDotsNumber VARCHAR(255) DEFAULT '';
DECLARE finalNumber VARCHAR(255) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti INTEGER DEFAULT 1;
DECLARE digitSequenceStarted boolean DEFAULT false;
DECLARE negativeNumber boolean DEFAULT false;
-- FIX FIND_IN_SET cannot find a comma ","
SET in_string_parsed = replace(in_string,',','.');
IF LENGTH(in_string_parsed) > 0 THEN
-- extract digits and dots
WHILE(inti <= LENGTH(in_string_parsed)) DO
SET sChar = SUBSTRING(in_string_parsed, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9,.');
IF ctrNumber > 0 AND (sChar != '.' OR LENGTH(digitsAndDotsNumber) > 0) THEN
-- add first minus if needed
IF digitSequenceStarted = false AND inti > 1 AND SUBSTRING(in_string_parsed, inti-1, 1) = '-' THEN
SET negativeNumber = true;
END IF;
SET digitSequenceStarted = true;
SET digitsAndDotsNumber = CONCAT(digitsAndDotsNumber, sChar);
ELSEIF digitSequenceStarted = true THEN
SET inti = LENGTH(in_string_parsed);
END IF;
SET inti = inti + 1;
END WHILE;
-- remove dots from the end of number list
SET inti = LENGTH(digitsAndDotsNumber);
WHILE(inti > 0) DO
IF(SUBSTRING(digitsAndDotsNumber, inti, 1) = '.') THEN
SET digitsAndDotsNumber = SUBSTRING(digitsAndDotsNumber, 1, inti-1);
SET inti = inti - 1;
ELSE
SET inti = 0;
END IF;
END WHILE;
-- extract decimal
SET inti = 1;
WHILE(inti <= LENGTH(digitsAndDotsNumber)-3) DO
SET sChar = SUBSTRING(digitsAndDotsNumber, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finalNumber = CONCAT(finalNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
SET finalNumber = CONCAT(finalNumber, RIGHT(digitsAndDotsNumber, 3));
IF negativeNumber = true AND LENGTH(finalNumber) > 0 THEN
SET finalNumber = CONCAT('-', finalNumber);
END IF;
IF LENGTH(finalNumber) = 0 THEN
RETURN 0;
END IF;
RETURN CAST(finalNumber AS decimal(15,2));
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
Tests:
select ExtractDecimal("1234"); -- 1234.00
select ExtractDecimal("12.34"); -- 12.34
select ExtractDecimal("1.234"); -- 1234.00
select ExtractDecimal("1,234"); -- 1234.00
select ExtractDecimal("1,111,234"); -- 11111234.00
select ExtractDecimal("11,112,34"); -- 11112.34
select ExtractDecimal("11,112,34 and 123123"); -- 11112.34
select ExtractDecimal("-1"); -- -1.00
select ExtractDecimal("hello. price is 123"); -- 123.00
select ExtractDecimal("123,45,-"); -- 123.45
Here is my improvement over ExtractNumber function by Eugene Yarmash.
It strips not only non-digit characters, but also HTML entities like &#[0-9];, which should be considered as non-digit unicode characters too.
Here is the code without UDP on pure MySQL <8.
CREATE DEFINER = 'user'#'host' FUNCTION `extract_number`(
str CHAR(255)
)
RETURNS char(255) CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci
DETERMINISTIC
NO SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE tmp VARCHAR(255);
DECLARE res VARCHAR(255) DEFAULT "";
DECLARE chr VARCHAR(1);
DECLARE len INTEGER UNSIGNED DEFAULT LENGTH(str);
DECLARE i INTEGER DEFAULT 1;
IF len > 0 THEN
WHILE i <= len DO
SET chr = SUBSTRING(str, i, 1);
/* remove &#...; */
IF "&" = chr AND "#" = SUBSTRING(str, i+1, 1) THEN
WHILE (i <= len) AND (";" != SUBSTRING(str, i, 1)) DO
SET i = i + 1;
END WHILE;
END IF;
SET tmp = FIND_IN_SET(chr, "0,1,2,3,4,5,6,7,8,9");
IF tmp > 0 THEN
SET res = CONCAT(res, chr);
END IF;
SET i = i + 1;
END WHILE;
RETURN res;
END IF;
RETURN 0;
END;
But if you are using UDP's PREG_REPLACE, you can use just following line:
RETURN PREG_REPLACE("/[^0-9]/", "", PREG_REPLACE("/&#[0-9]+;/", "", str));
I have rewritten this for MemSQL Syntax:
DROP FUNCTION IF EXISTS GetNumeric;
DELIMITER //
CREATE FUNCTION GetNumeric(str CHAR(255)) RETURNS CHAR(255) AS
DECLARE i SMALLINT = 1;
DECLARE len SMALLINT = 1;
DECLARE ret CHAR(255) = '';
DECLARE c CHAR(1);
BEGIN
IF str IS NULL
THEN
RETURN "";
END IF;
WHILE i < CHAR_LENGTH( str ) + 1 LOOP
BEGIN
c = SUBSTRING( str, i, 1 );
IF c BETWEEN '0' AND '9' THEN
ret = CONCAT(ret,c);
END IF;
i = i + 1;
END;
END LOOP;
RETURN ret;
END //
DELIMITER ;
SELECT GetNumeric('abc123def456xyz789') as test;
Based on Eugene Yarmash and Martins Balodis answers.
In my case, I didn't know whether the source string contains dot as a decimal separator. Although, I knew how the specific column should be treated. E.g. in case value came up as "10,00" hours but not as "1.00" we know that the last delimiter character should be treated as a dot decimal separator. For this purposes, we can rely on a secondary boolean param that specifies how the last comma separator should behave.
DELIMITER $$
CREATE FUNCTION EXTRACT_DECIMAL(
inString VARCHAR(255)
, treatLastCommaAsDot BOOLEAN
) RETURNS varchar(255) CHARSET utf8mb4
NO SQL
DETERMINISTIC
BEGIN
DECLARE ctrNumber VARCHAR(255);
DECLARE inStringParsed VARCHAR(255);
DECLARE digitsAndDotsNumber VARCHAR(255) DEFAULT '';
DECLARE digitsBeforeDotNumber VARCHAR(255) DEFAULT '';
DECLARE digitsAfterDotNumber VARCHAR(255) DEFAULT '';
DECLARE finalNumber VARCHAR(255) DEFAULT '';
DECLARE separatorChar VARCHAR(1) DEFAULT '_';
DECLARE iterChar VARCHAR(1);
DECLARE inti INT DEFAULT 1;
DECLARE digitSequenceStarted BOOLEAN DEFAULT false;
DECLARE negativeNumber BOOLEAN DEFAULT false;
-- FIX FIND_IN_SET cannot find a comma ","
-- We need to separate entered dot from another delimiter characters.
SET inStringParsed = TRIM(REPLACE(REPLACE(inString, ',', separatorChar), ' ', ''));
IF LENGTH(inStringParsed) > 0 THEN
-- Extract digits, dots and delimiter character.
WHILE(inti <= LENGTH(inStringParsed)) DO
-- Might contain MINUS as the first character.
SET iterChar = SUBSTRING(inStringParsed, inti, 1);
SET ctrNumber = FIND_IN_SET(iterChar, CONCAT('0,1,2,3,4,5,6,7,8,9,.,', separatorChar));
-- In case the first extracted character is not '.' and `digitsAndDotsNumber` is set.
IF ctrNumber > 0 AND (iterChar != '.' OR LENGTH(digitsAndDotsNumber) > 0) THEN
-- Add first minus if needed. Note: `inti` at this point will be higher than 1.
IF digitSequenceStarted = FALSE AND inti > 1 AND SUBSTRING(inStringParsed, inti - 1, 1) = '-' THEN
SET negativeNumber = TRUE;
END IF;
SET digitSequenceStarted = TRUE;
SET digitsAndDotsNumber = CONCAT(digitsAndDotsNumber, iterChar);
ELSEIF digitSequenceStarted = true THEN
SET inti = LENGTH(inStringParsed);
END IF;
SET inti = inti + 1;
END WHILE;
-- Search the left part of string until the separator.
-- https://stackoverflow.com/a/43699586
IF (
-- Calculates the amount of delimiter characters.
CHAR_LENGTH(digitsAndDotsNumber)
- CHAR_LENGTH(REPLACE(digitsAndDotsNumber, separatorChar, SPACE(LENGTH(separatorChar)-1)))
) + (
-- Calculates the amount of dot characters.
CHAR_LENGTH(digitsAndDotsNumber)
- CHAR_LENGTH(REPLACE(digitsAndDotsNumber, '.', SPACE(LENGTH(separatorChar)-1)))
) > 0 THEN
-- If dot is present in the string. It doesn't matter for the other characters.
IF LOCATE('.', digitsAndDotsNumber) != FALSE THEN
-- Replace all special characters before the dot.
SET inti = LOCATE('.', digitsAndDotsNumber) - 1;
-- Return the first half of numbers before the last dot.
SET digitsBeforeDotNumber = SUBSTRING(digitsAndDotsNumber, 1, inti);
SET digitsBeforeDotNumber = REPLACE(digitsBeforeDotNumber, separatorChar, '');
SET digitsAfterDotNumber = SUBSTRING(digitsAndDotsNumber, inti + 2, LENGTH(digitsAndDotsNumber) - LENGTH(digitsBeforeDotNumber));
SET digitsAndDotsNumber = CONCAT(digitsBeforeDotNumber, '.', digitsAfterDotNumber);
ELSE
IF treatLastCommaAsDot = TRUE THEN
-- Find occurence of the last delimiter within the string.
SET inti = CHAR_LENGTH(digitsAndDotsNumber) - LOCATE(separatorChar, REVERSE(digitsAndDotsNumber));
-- Break the string into left part until the last occurrence of separator character.
SET digitsBeforeDotNumber = SUBSTRING(digitsAndDotsNumber, 1, inti);
SET digitsBeforeDotNumber = REPLACE(digitsBeforeDotNumber, separatorChar, '');
SET digitsAfterDotNumber = SUBSTRING(digitsAndDotsNumber, inti + 2, LENGTH(digitsAndDotsNumber) - LENGTH(digitsBeforeDotNumber));
-- Remove any dot occurence from the right part.
SET digitsAndDotsNumber = CONCAT(digitsBeforeDotNumber, '.', REPLACE(digitsAfterDotNumber, '.', ''));
ELSE
SET digitsAndDotsNumber = REPLACE(digitsAndDotsNumber, separatorChar, '');
END IF;
END IF;
END IF;
SET finalNumber = digitsAndDotsNumber;
IF negativeNumber = TRUE AND LENGTH(finalNumber) > 0 THEN
SET finalNumber = CONCAT('-', finalNumber);
END IF;
IF LENGTH(finalNumber) = 0 THEN
RETURN 0;
END IF;
RETURN CAST(finalNumber AS DECIMAL(25,5));
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
Here are some examples of usage:
--
-- SELECT EXTRACT_DECIMAL('-711,712,34 and 123123', FALSE); -- -71171234.00000
-- SELECT EXTRACT_DECIMAL('1.234', FALSE); -- 1.23400
-- SELECT EXTRACT_DECIMAL('1,234.00', FALSE); -- 1234.00000
-- SELECT EXTRACT_DECIMAL('14 9999,99', FALSE); -- 14999999.00000
-- SELECT EXTRACT_DECIMAL('-149,999.99', FALSE); -- -149999.99000
-- SELECT EXTRACT_DECIMAL('3 536 500.53', TRUE); -- 3536500.53000
-- SELECT EXTRACT_DECIMAL('3,536,500,53', TRUE); -- 3536500.53000
-- SELECT EXTRACT_DECIMAL("-1"); -- -1.00000
-- SELECT EXTRACT_DECIMAL('2,233,536,50053', TRUE); -- 2233536.50053
-- SELECT EXTRACT_DECIMAL('13.01666667', TRUE); -- 13.01667
-- SELECT EXTRACT_DECIMAL('1,00000000', FALSE); -- 100000000.00000
-- SELECT EXTRACT_DECIMAL('1000', FALSE); -- 1000.00000
-- ==================================================================================
Try,
Query level,
SELECT CAST('1&hash' AS UNSIGNED);
for PHP,
echo intval('13213&hash');
For any newcomers with a similar request this should be exactly what you need.
select DISTINCT CONVERT(SUBSTRING(referrerURL,71,6), SIGNED) as `foo`
from hotshotsdblog1.annonymoustracking
where advertiserid = 10
limit 10;
I suggest using a pivot table (e.g., a table that only contains a vector of ordered numbers from 1 to at least the length of the string) and then doing the following:
SELECT group_concat(c.elem separator '')
from (
select b.elem
from
(
select substr('PAUL123f3211',iter.pos,1) as elem
from (select id as pos from t10) as iter
where iter.pos <= LENGTH('PAUL123f3211')
) b
where b.elem REGEXP '^[0-9]+$') c
It can be done in PHP instead.
foreach ($query_result as &$row) {
$row['column_with_numbers'] = (int) filter_var($query_result['column_with_numbers'], FILTER_SANITIZE_NUMBER_INT);
}
Try this in php
$string = '9072&h';
echo preg_replace("/[^0-9]/", '', $string);// output: 9072
or follow this link to do this in MySql
Refer the link

Case not working for my stored procedure

I have created this procedure to insert upc_id and relevent values in the table product_universal_description.
CREATE PROCEDURE veealpha
(
IN s_po_id INT(11),
IN s_supplier_id INT(11),
IN s_location_id VARCHAR(32),
IN s_warehouse_id INT(11),
IN s_user_id INT(11),
OUT message VARCHAR(64),
OUT error_code INT(4)
)
BEGIN
DECLARE temp_upc VARCHAR(32);
DECLARE i INT;
DECLARE finished INTEGER DEFAULT 0;
DECLARE loop_count int(4);
DECLARE upc varchar(32);
DECLARE p_product_id int(11);
DECLARE p_model varchar(64);
DECLARE counter_cursor CURSOR FOR
SELECT product_id,model,quantity FROM product
WHERE model in('CFB0040','CFB0042','CFB0043','CFB0044')
AND quantity > 0;
DECLARE CONTINUE HANDLER FOR 1062
SET message = 'Duplicate Keys Found';
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET finished = 1;
OPEN counter_cursor;
add_data : LOOP
FETCH counter_cursor INTO p_product_id, p_model, loop_count;
SET i = 1;
WHILE loop_count > 0 DO
CASE i
WHEN i < 10 THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-000',i);
WHEN (i >= 10 AND i < 100) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-00',i);
WHEN (i >= 100 AND i < 1000) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-0',i);
ELSE
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-',i);
END CASE;
INSERT INTO product_universal_description
(
`upc_id`,
`po_id`,
`supplier_id`,
`location_id`,
`warehouse_id`,
`product_id`,
`model_no`,
`added_by`,
`updated_by`,
`date_added`,
`date_modified`
) VALUES (
temp_upc,
s_po_id,
s_supplier_id,
s_location_id,
s_warehouse_id,
p_product_id,
p_model,
s_user_id,
s_user_id,
NOW(),
NOW()
);
SET i=i+1;
SET loop_count = loop_count - 1;
END WHILE;
IF finished = 1 THEN
LEAVE add_data;
END IF;
END LOOP add_data;
CLOSE counter_cursor;
END
CALL veealpha(123,45,'UP',1,56,#msg,#err);
ON Execution I getting the result like this.
How ever I have given the conditions there for UPC_ID that it should be well mannered as per case. But leaving for i = 1 FOR all it takes the ELSE condition at CASE. Can anybody tell me .. what's wrong happened and how could i get the desired result.
Try:
...
-- CASE i
CASE
WHEN i < 10 THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-000',i);
WHEN (i >= 10 AND i < 100) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-00',i);
WHEN (i >= 100 AND i < 1000) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-0',i);
ELSE
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-',i);
END CASE;
...

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;