Why my Sql Script does not work? - mysql

I am newbie to MySQL
I am trying to generate random data and put it into table 'data'
But SQL shell says that my sql code have syntax error
But I can't find why
DECLARE #counter smallint;
DECLARE #A BOOLEAN;
DECLARE #B BOOLEAN;
DECLARE #C int(4);
DECLARE #LABEL BOOLEAN;
SET #counter = 1;
WHILE #counter < 100
BEGIN
IF 0.5 > RAND()
SET #A = TRUE;
ELSE
SET #A = FALSE;
IF 0.5 > RAND()
SET #B = TRUE;
ELSE
SET #B = FALSE;
SET #C = RAND() * 10
SET #LABEL = #A ^ #B OR #LABEL > 5
INSERT INTO data (A,B,C,LABEL) VALUES (#A,#B,#C,#LABEL)
#count = #count +1
END
It says that I have syntax problem
from declaring variables
can you help me?

Is missing some syntax words:
IF... THEN ... ELSE ... END IF;
WHILE ... DO ... END WHILE;
Is important understand that user variables are written as #var_name, so user-defined variables are session-specific. That is, a user variable defined by one client cannot be seen or used by other clients. All variables for a given client session are automatically freed when that client exits. In this case, I think that is not necessary.
SET, either = or := can be used as the assignment operator.
Try this:
delimiter //
CREATE PROCEDURE TEST()
BEGIN
DECLARE counter smallint;
DECLARE A BOOLEAN;
DECLARE B BOOLEAN;
DECLARE C int(4);
DECLARE LABEL BOOLEAN;
SET counter = 1;
WHILE counter < 100 DO
IF 0.5 > RAND() THEN
SET A = TRUE;
ELSE
SET A = FALSE;
END IF;
IF 0.5 > RAND() THEN
SET B = TRUE;
ELSE
SET B = FALSE;
END IF;
SET C = RAND() * 10;
IF A ^ B OR LABEL > 5 THEN
SET LABEL = TRUE;
ELSE
SET LABEL = FALSE;
END IF;
INSERT INTO data (A,B,C,LABEL) VALUES (A,B,C,LABEL);
SET counter = counter +1;
END WHILE;
END//

try this,
DECLARE #counter smallint,
DECLARE #A BOOLEAN,
DECLARE #B BOOLEAN,
DECLARE #C int(4),
DECLARE #LABEL BOOLEAN;

Related

mySQL procedure does not commit on commit statement

This is my code:
BEGIN
DECLARE _cnt INT;
DECLARE i INT DEFAULT 0 ;
DECLARE j INT DEFAULT 0 ;
DECLARE _FIPSAPNCombo VARCHAR(30) DEFAULT '00000';
DECLARE _prv_FIPSAPNCombo VARCHAR(30) DEFAULT '00000';
DECLARE _Rollyear INT DEFAULT 2000;
DECLARE _first_Rollyear INT DEFAULT 2000;
DECLARE eof boolean default FALSE;
DECLARE _AvTotal INT;
DECLARE _prv_AvTotal INT default 0;
DECLARE _YOY_PCT INT;
DECLARE _YOY_USD INT;
DECLARE _in_pct INT;
DECLARE _in_usd INT;
DECLARE _last INT;
DECLARE _id INT;
DECLARE _idx INT;
DECLARE _prv_id INT;
DECLARE get_FIPSAPNCombo CURSOR
FOR
SELECT 0, '0', 2000, 1
UNION
SELECT id, FIPSAPNCombo, rollyear, AvTotal
FROM AvHistory_06037 AS h
WHERE substr(h.FIPSAPNCombo,1,8) = _in_FIPSAPNCombo_8
AND h.AvTotal > 0
ORDER BY 2, 3
;
DECLARE CONTINUE HANDLER
FOR NOT FOUND
SET eof = TRUE;
SELECT YOY_PCT, YOY_USD INTO _in_pct, _in_usd FROM AlertSearches WHERE id = _in_AlertSearchesID;
START TRANSACTION;
OPEN get_FIPSAPNCombo;
doit: LOOP
fetch get_FIPSAPNCombo INTO _id, _FIPSAPNCombo, _Rollyear, _AvTotal;
SET _YOY_USD = _AvTotal - _prv_AvTotal;
SET _YOY_PCT = ROUND((((_AvTotal - _prv_AvTotal) / _prv_AvTotal) * 100),0);
IF eof = TRUE THEN
LEAVE doit;
END IF;
IF _FIPSAPNCombo != _prv_FIPSAPNCombo THEN SET _first_Rollyear = _Rollyear; ELSE SET _first_Rollyear = '2000'; END IF;
IF _YOY_PCT >= _in_pct AND _YOY_USD >= _in_usd and _Rollyear != _first_Rollyear THEN
BEGIN
DELETE FROM AvHistoryAlerts WHERE FIPSAPNCombo = _FIPSAPNCombo AND AlertSearchesID = _in_AlertSearchesID;
INSERT INTO AvHistoryAlerts VALUES (_id, _FIPSAPNCombo, '06037', _Rollyear, _AvTotal, _YOY_PCT, _YOY_USD, _prv_id, _prv_AvTotal, _in_AlertSearchesID);
UPDATE AvHistory SET CausalTransfer = NULL WHERE FIPSAPNCombo = _FIPSAPNCombo;
UPDATE AvHistory SET CausalTransfer = 'Green' WHERE id = _id;
SET i = i + 1;
IF mod(i,1000) = 0 THEN insert into error_log VALUES (concat(_in_FIPSAPNCombo_8, ' > calc_YOY_increase i = ', i, ' ',now())); COMMIT; START TRANSACTION; END IF;
END;
END IF;
SET _prv_FIPSAPNCombo = _FIPSAPNCombo;
SET _prv_AvTotal = _AvTotal;
SET _prv_id = _id;
SET eof = FALSE;
END LOOP;
COMMIT;
CLOSE get_FIPSAPNCombo;
END
I thought that the procedure would commit every 1000 records processed and that this would be reflected in the error_log table in real time.
But, the data is only available after the procedure finishes completely and then all the records show up all at once in the error_log table.
That, by itself, is not the issue: what I am concerned about is the the procedure seems to dwell on "waiting for handler commit" for a long time at the end of the procedure.
So, I'm not sure what's going on: is it storing everything in memory or in a temp table or file and then needs a lot if time for cleanup?
I thought that a commit would clear all that... but it does not seem to commit until the end of the whole procedure
Any ideas?

How to remove Vietnamese Character in MySQL

My Code MYSQL
DELIMITER //
CREATE FUNCTION fNonUnicode(p_inputVar LONGTEXT )
RETURNS LONGTEXT
BEGIN
IF (p_inputVar IS NULL OR p_inputVar = '') THEN RETURN '';
END IF;
DECLARE v_RT LONGTEXT;
DECLARE v_SIGN_CHARS NVARCHAR(256);
DECLARE v_UNSIGN_CHARS NVARCHAR (256);
SET v_SIGN_CHARS = Concat(N'ăâđêôơưàảãạáằẳẵặắầẩẫậấèẻẽẹéềểễệếìỉĩịíòỏõọóồổỗộốờởỡợớùủũụúừửữựứỳỷỹỵýĂÂĐÊÔƠƯÀẢÃẠÁẰẲẴẶẮẦẨẪẬẤÈẺẼẸÉỀỂỄỆẾÌỈĨỊÍÒỎÕỌÓỒỔỖỘỐỜỞỠỢỚÙỦŨỤÚỪỬỮỰỨỲỶỸỴÝ' , NCHAR(272) + NCHAR(208));
SET v_UNSIGN_CHARS = N'aadeoouaaaaaaaaaaaaaaaeeeeeeeeeeiiiiiooooooooooooooouuuuuuuuuuyyyyyAADEOOUAAAAAAAAAAAAAAAEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOUUUUUUUUUUYYYYYDD';
DECLARE v_COUNTER int;
DECLARE v_COUNTER1 int;
SET v_COUNTER = 1;
WHILE (v_COUNTER <= CHAR_LENGTH(RTRIM(p_inputVar)))
DO
SET v_COUNTER1 = 1;
WHILE (v_COUNTER1 <= CHAR_LENGTH(RTRIM(v_SIGN_CHARS)) + 1)
DO
IF UNICODE(SUBSTRING(v_SIGN_CHARS, v_COUNTER1,1)) = UNICODE(SUBSTRING(p_inputVar,v_COUNTER ,1))
THEN
IF v_COUNTER = 1 THEN
SET p_inputVar = CONCAT(SUBSTRING(v_UNSIGN_CHARS, v_COUNTER1,1) , SUBSTRING(p_inputVar, v_COUNTER+1,CHAR_LENGTH(RTRIM(p_inputVar))-1));
ELSE
SET p_inputVar = CONCAT(SUBSTRING(p_inputVar, 1, v_COUNTER-1) ,SUBSTRING(v_UNSIGN_CHARS, v_COUNTER1,1) , SUBSTRING(p_inputVar, v_COUNTER+1,CHAR_LENGTH(RTRIM(p_inputVar))- v_COUNTER));
END IF;
BREAK
END IF;
SET v_COUNTER1 = v_COUNTER1 +1;
END WHILE;
SET v_COUNTER = v_COUNTER +1;
END WHILE;
-- SET #inputVar = replace(#inputVar,' ','-')
RETURN p_inputVar;
END;
//
DELIMITER ;
But Error:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DECLARE v_RT LONGTEXT;
Finnaly: I want to use:fNonUnicode("Xin chào các bạn") return Xin chao cac ban
MySQL Function to remove accents and special characters
DROP FUNCTION IF EXISTS fn_remove_accents;
DELIMITER |
CREATE FUNCTION fn_remove_accents( textvalue VARCHAR(10000) ) RETURNS VARCHAR(10000)
BEGIN
SET #textvalue = textvalue;
-- ACCENTS
SET #withaccents = 'ŠšŽžÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝŸÞàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿþƒ';
SET #withoutaccents = 'SsZzAAAAAAACEEEEIIIINOOOOOOUUUUYYBaaaaaaaceeeeiiiinoooooouuuuyybf';
SET #count = LENGTH(#withaccents);
WHILE #count > 0 DO
SET #textvalue = REPLACE(#textvalue, SUBSTRING(#withaccents, #count, 1), SUBSTRING(#withoutaccents, #count, 1));
SET #count = #count - 1;
END WHILE;
-- SPECIAL CHARS
SET #special = '!##$%¨&*()_+=§¹²³£¢¬"`´{[^~}]<,>.:;?/°ºª+*|\\''';
SET #count = LENGTH(#special);
WHILE #count > 0 do
SET #textvalue = REPLACE(#textvalue, SUBSTRING(#special, #count, 1), '');
SET #count = #count - 1;
END WHILE;
RETURN #textvalue;
END
|
DELIMITER ;
please try with code below
DROP FUNCTION IF EXISTS fn_remove_accents;
DELIMITER //
CREATE FUNCTION fn_remove_accents(textvalue TEXT)
RETURNS TEXT
BEGIN
SET #textvalue = textvalue;
-- ACCENTS
SET #withaccents = 'ăâđêôơưàảãạáằẳẵặắầẩẫậấèẻẽẹéềểễệếìỉĩịíòỏõọóồổỗộốờởỡợớùủũụúừửữựứỳỷỹỵýĂÂĐÊÔƠƯÀẢÃẠÁẰẲẴẶẮẦẨẪẬẤÈẺẼẸÉỀỂỄỆẾÌỈĨỊÍÒỎÕỌÓỒỔỖỘỐỜỞỠỢỚÙỦŨỤÚỪỬỮỰỨỲỶỸỴÝ';
SET #withoutaccents = 'aadeoouaaaaaaaaaaaaaaaeeeeeeeeeeiiiiiooooooooooooooouuuuuuuuuuyyyyyAADEOOUAAAAAAAAAAAAAAAEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOUUUUUUUUUUYYYYY';
SET #count = LENGTH(#withaccents);
WHILE #count > 0 DO
SET #textvalue = REPLACE(#textvalue, SUBSTRING(#withaccents, #count, 1), SUBSTRING(#withoutaccents, #count, 1));
SET #count = #count - 1;
END WHILE;
RETURN #textvalue;
END
//
DELIMITER ;

MySQL substring in function not returning whitespace

I have a function that is for changing text into proper case.
CREATE FUNCTION `fpropercasetest` (p_Value VARCHAR(8000))
RETURNS VARCHAR(8000)
BEGIN
DECLARE v_i INT; -- counter
DECLARE v_ProperCaseText VARCHAR(5000);
DECLARE v_Word VARCHAR(1000);
DECLARE v_isWhiteSpace TINYINT(1);
DECLARE v_c CHAR(1);
SET v_Word = '';
SET v_i = 1;
SET v_isWhiteSpace = 1;
SET v_ProperCaseText = '';
SET p_Value = LOWER(p_Value);
WHILE (v_i <= LENGTH(p_Value)+1) DO
SET v_c = SUBSTRING(p_Value,v_i,1);
IF v_isWhiteSpace = 1 THEN SET v_c = UPPER(v_c); END IF;
SET v_isWhiteSpace = CASE WHEN (ASCII(v_c) BETWEEN 48 AND 58) THEN 0
WHEN (ASCII(v_c) BETWEEN 64 AND 90) THEN 0
WHEN (ASCII(v_c) BETWEEN 96 AND 123) THEN 0
ELSE 1 END;
IF v_isWhiteSpace = 0 THEN
SET v_Word = CONCAT(v_Word, v_c);
ELSE
SET v_ProperCaseText = CONCAT(v_ProperCaseText, v_Word, v_c);
SET v_Word = '';
END IF;
SET v_i = v_i + 1;
END WHILE;
return v_ProperCaseText;
END;
You can test with the following
SELECT fpropercasetest("this is just some text for you to test with");
When I entered any text with spaces I noticed that it just didn't register (e.g. with the text "this is some text" it would return "ThisIsSomeText" and it should return "This Is Some Text")
I debugged it with Visual Studio and noticed that substring was just ignoring spaces completely, it returns an empty string.
I'm completely stumped by this, any help will be greatly appreciated. Thanks.
Sorry about the delay, I had a few things to take care of before leaving work, here is what I came up with, it does what you want it to do:
FUNCTION `upper_all`(p_Value VARCHAR(8000)) RETURNS varchar(8000) CHARSET latin1
BEGIN
DECLARE pos INT; -- counter
DECLARE result VARCHAR(1000);
SET p_Value = LOWER(p_Value);
SET p_Value = CONCAT(UCASE(LEFT(p_Value, 1)),LCASE(SUBSTRING(p_Value, 2)));
SET pos = LOCATE(' ',p_Value);
SET result = SUBSTR(p_Value,1,LOCATE(' ',p_Value));
SET p_Value = SUBSTR(p_Value FROM pos);
WHILE (pos > 0) DO
/*SET p_Value = CONCAT(p_Value,UCASE(LEFT(p_Value, pos)),LCASE(SUBSTRING(p_Value, 2)));*/
SET pos = LOCATE(' ',p_Value);
IF pos > 0 THEN
SET pos = pos + 1;
SET p_Value = SUBSTR(p_Value FROM pos);
END IF;
SET p_Value = CONCAT(UCASE(LEFT(p_Value, 1)),LCASE(SUBSTRING(p_Value, 2)));
SET result = CONCAT(result,SUBSTR(p_Value,1,LOCATE(' ',p_Value)));
END WHILE;
SET result = CONCAT(result,p_Value);
return result;
END
I didn't have time to comment it out for you, it should self-explanatory. It could use a little cleanup and optimize the code a bit.
create function fn_title_case
(v_input_string varchar(255))
RETURNS varchar(255)
BEGIN
declare i int;
DECLARE punctuation varchar(17);
declare this_character char(1);
declare output_string varchar(255);
declare boolean_value int;
declare input_length int;
set input_length = char_length(v_input_string);
set boolean_value = 0;
set i = 0;
set punctuation = ' ';
set output_string = '';
begin
-- Loop through each character in the input string
while i <= input_length do
-- Set the current substring to position i with length 1
SET this_character = SUBSTRING( v_input_string, i, 1 );
-- If the current character exists in the punctuation string, i.e. if the current character is a space
IF LOCATE( this_character, punctuation ) > 0 THEN
-- Set the current character to null and the boolean to 1
set this_character = '', output_string = concat(output_string, this_character), boolean_value = 1;
elseif boolean_value=1 then
-- Only if the punctuation (a space) was detected in the previous step,
-- Insert a space and capitalize the letter
SET output_string = concat(output_string, ' ', UCASE(this_character)), boolean_value = 0;
else
-- If the space was NOT detected, add the current character in lower case
set output_string = concat(output_string, LCASE(this_character));
end if;
set i = i+1;
end while;
end;
RETURN output_string;

MySQL Proc Call - Set Strange Behaviour

I Have a table somewhat like this:
rnumber
number = int, cod = int
SELECT * FROM number WHERE number = 21377 and cod = 55;
returns the correct value;
So i have a proc call to insert:
CREATE DEFINER=`root`#`%` PROCEDURE `create`(IN Numb INT, IN Cod INT, IN qt INT)
BEGIN
SET #Cont = 0;
SET #Init = Numb;
WHILE #Cont < qt DO
SET #Exist = (SELECT count(number) FROM rnumber WHERE number = #Init AND cod = Cod LIMIT 1);
IF #Exist = 0 THEN
INSERT INTO (...)
END IF;
SET #Cont = #Cont + 1;
SET #IniT = #Init + 1;
END WHILE;
END$$
CALL create (21377, 54, 1);
Always give me variable #Exist as 1, so no go on the if, even tho the combination of number and cod does not exists.
Can anyone point me what am i doing wrong?
Thank you.
Try using select into instead of set xx = (select...).
Also having cod = Cod will always return true...
You also need to declare your variables...
Try this one:
CREATE DEFINER=`root`#`%` PROCEDURE `create`(IN p_Numb INT, IN p_Cod INT, IN p_qt INT)
BEGIN
declare v_Exist integer;
declare v_Init integer;
declare v_Exist integer;
SET v_Cont = 0;
SET v_Exist = 0;
SET v_Init = p_Numb;
WHILE v_Cont < p_qt DO
SELECT count(number) into v_Exist FROM rnumber WHERE number = v_Init AND cod = p_Cod LIMIT 1;
IF v_Exist = 0 THEN
INSERT INTO (...)
END IF;
SET v_Cont = v_Cont +1;
SET v_IniT = v_Init + 1;
END WHILE;
END$$

MySQL build a variable name?

I am trying to build a variable name dynamically within a user defined function but it seems it does not work. Is there a way to do this or by using an array variable?
I have a string of 7 characters which represents the days of the week (1234567, or 1_3_5_7, etc.). I would like evaluate how often during a week a day is selected (from 0 to 7). I thought, it would be easiest to use a loop to go through all the 7 positions but I get an error message saying
[Err] 1193 - Unknown system variable 'CONCAT'
Any hints on how I can achieve that? This is my code:
DELIMITER $$
DROP FUNCTION IF EXISTS fn_freq$$
CREATE FUNCTION fn_freq(days INT) RETURNS INT
BEGIN
DECLARE D1 VARCHAR(1);
DECLARE D2 VARCHAR(1);
DECLARE D3 VARCHAR(1);
DECLARE D4 VARCHAR(1);
DECLARE D5 VARCHAR(1);
DECLARE D6 VARCHAR(1);
DECLARE D7 VARCHAR(1);
DECLARE x INT;
DECLARE fn_freq INT;
SET x =1;
SET fn_freq = 0;
WHILE x < 8 DO
SET CONCAT('D',x) = MID(days, x, 1);
IF CONCAT('D',x) = '_' THEN
ELSE
SET fn_freq = fn_freq + 1;
SET x = x + 1;
END IF;
SET x = x + 1;
END WHILE;
RETURN fn_freq;
END$$
DELIMITER ;
You cant SET CONCAT as in SET CONCAT('D',x) = MID(days, x, 1) what instead i think will be better to declare & set the concat value to that variable and use that variable for the IF condition. Also I think you missed out what have to be done in the case IF Condition is true.
Thanks for your reply. I got it to work like this, but I am still curious, how I could dynamically create a variable in some other cases.
For this function, I realized I don't even need the variable, as I can evaluate it straight in the if clause.
DELIMITER $$
DROP FUNCTION IF EXISTS fn_freq$$
CREATE FUNCTION fn_freq(days VarChar(7)) RETURNS INT
BEGIN
DECLARE x INT;
DECLARE fn_freq INT;
SET x =1, fn_freq = 0;
WHILE x < 8 DO
IF MID(days, x, 1) <> '_' THEN
SET fn_freq = fn_freq + 1;
END IF;
SET x = x + 1;
END WHILE;
RETURN fn_freq;
END$$
DELIMITER ;