A little present for all;
This function (for MYSQL DATABASE) return a discounted price using commercial discount format eg: 50+20+3 …
Example : SELECT f_sconti(10000,‘50+20+3’) as price …
If use DISCOUNT and INCREASE see :
SELECT f_sconti(10000,‘50+20-3’) as price …
DROP FUNCTION f_sconti;
DELIMITER $$
CREATE FUNCTION f_sconti(
valore double precision,
sconto text)
RETURNS double precision
BEGIN
DECLARE elementi INT;
DECLARE contatore INT;
DECLARE stringa text;
DECLARE parte text;
SET contatore := 1; /* imposto il contatore a 0' */
SET stringa := REPLACE(sconto,',','.'); /* prima rimpiazzo le virgole con i punti */
SET stringa := REPLACE(stringa,'+',',+'); /* poi rimpiazzo i '+' con ',+' */
SET stringa := REPLACE(stringa,'-',',-'); /* poi rimpiazzo i '-' con ',-' */
SET elementi := count_str(stringa,',')+2;
IF sconto = '' THEN
RETURN valore;
END IF;
IF elementi > 0 THEN
conta: REPEAT
SET valore := valore - (valore * CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(stringa,',',contatore),',',-1) AS DECIMAL(10,3)) / 100);
SET contatore := contatore + 1;
UNTIL contatore = elementi
END REPEAT conta;
ELSE
RETURN valore;
END IF;
RETURN valore;
END $$
END ;
DELIMITER ;
And the function for count substring occurrence in a string
CREATE DEFINER=`root`@`localhost` FUNCTION `count_str`(testo TEXT, separatore TEXT) RETURNS int(11)
BEGIN
RETURN ROUND((CHAR_LENGTH(testo) - CHAR_LENGTH(REPLACE(testo, separatore, ""))) / CHAR_LENGTH(separatore));
END
And the same function for POSTGREESQL
CREATE OR REPLACE FUNCTION public.f_sconti(
valore double precision,
sconto text)
RETURNS double precision AS
$BODY$DECLARE
elementi INT;
contatore INT;
stringa text;
parte text[];
BEGIN
contatore := 0; /* imposto il contatore a 0' */
stringa := REPLACE(sconto,',','.'); /* prima rimpiazzo le virgole con i punti */
stringa := REPLACE(stringa,'+',',+'); /* poi rimpiazzo i '+' con ',+' */
stringa := REPLACE(stringa,'-',',-'); /* poi rimpiazzo i '-' con ',-' */
parte := string_to_array(stringa, ',');
elementi := array_length(parte, 1);
IF sconto = '' THEN
RETURN valore;
END IF;
IF elementi > 0 THEN
FOR contatore IN 1..elementi LOOP
valore := valore - (valore * CAST(parte[contatore] AS float8) / 100);
END LOOP;
END IF;
RETURN valore;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER
COST 1000;
ALTER FUNCTION public.f_sconti(double precision, text)
OWNER TO postgres;