MySQL script error - mysql

I'm new to SQL programming and I decided to make a script. This one might be quite riddled with errors but I'm getting an error that I'm unable to resolve.
DELIMITER $
DROP FUNCTION IF EXISTS crossref$
CREATE FUNCTION crossref()
BEGIN
DECLARE i INT;
DECLARE names VARCHAR(70);
SET i = 1;
myloop: LOOP
SET i=i+1;
IF i = 6 then
LEAVE myloop;
END IF;
SET names = (SELECT NAME FROM cbase_excel_table WHERE ID = i);
INSERT INTO cbase_master(NAME, PERMALINK, HOMEPAGE_URL, CATEGORY_LIST, MARKET, FUNDING, 'STATUS', COUNTRY, REGION, CITY)
SELECT NAME, PERMALINK, HOMEPAGE_URL, CATEGORY_LIST, MARKET, FUNDING, 'STATUS', COUNTRY, REGION, CITY FROM cbase_excel_table WHERE ID = i;
UPDATE cbase_master
SET DESCRIPTION = (SELECT DESCRIPTION FROM cbase_json_table WHERE NAME = names)
SET DOMAIN = (SELECT DOMAIN FROM cbase_json_table WHERE NAME = names)
SET IMAGE_URL = (SELECT IMAGE_URL FROM cbase_json_table WHERE NAME = names)
SET FACEBOOK_URL = (SELECT FACEBOOK_URL FROM cbase_json_table WHERE NAME = names)
SET TWITTER_URL = (SELECT TWITTER_URL FROM cbase_json_table WHERE NAME = names)
SET LINKEDIN_URL = (SELECT LINKEDIN_URL FROM cbase_json_table WHERE NAME = names)
SET CBASE_UUID = (SELECT CBASE_UUID FROM cbase_json_table WHERE NAME = names);
END LOOP myloop;
END$
DELIMITER;
and I'm getting:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BEGIN
DECLARE i INT;
DECLARE names VARCHAR(70);
SET i = 1;
Any help?

An example of a function which shows a major difference to your function:
CREATE FUNCTION `fnFindMaximum`(`a` INT, `b` INT)
/* Before the BEGIN statement there are other things going on - the most important being the return type statement */
RETURNS int(11)
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE returnval INTEGER;
IF a >= b THEN
SET returnval = a;
ELSE
SET returnval = b;
END IF;
RETURN returnval;
END
Your function then goes on to manipulate sql but does not return a value so, as was pointed out by #arkhil, use a StoredProcedure in preference to a function.

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

SQL stored procedure local variable error #1064

I am working for a little film database with php and mysql. And i got a problem when I want to create a stored procedure, that the local variable don't work in the case i want to use it.
delimiter //
### showFilm###
create procedure showFilm( in id INTEGER )
BEGIN
DECLARE tmp_Value varchar(50);
IF ( id = 0) THEN SET tmp_Value = "";
ELSE SET tmp_Value = concat('where = ', id);
END IF;
select f.Titel, f.Jahr, f.Bewertung, f.altersfreigabe, f.Beschreibung, f.Trailer, f.Dateipfad, f.Titelbild, f.Speichermedium, r.Vorname, r.Nachname, r.Land, r.Bild
from film as f
inner join regisseur as r
on r.idRegisseur = f.idFilm tmp_Value;
END;
//

How Can I Create a MySQL Function to Check JSON Validity?

I'm fairly new to MySQL but I'd like to create a function to validate a JSON objects that are stored in my database tables.
I looked up information on creating a function, but must be missing something as I can't seem to get it to work. It doesn't seem like it would be overly complicated but perhaps I'm not using the appropriate syntax.
Here is my code:
DELIMITER //
CREATE FUNCTION CHECKJSON( DB_NAME varchar(255), TABLE_NAME varchar(255), JSON_COLUMN varchar(255))
RETURNS varchar(300)
BEGIN
DECLARE notNullCount int;
DECLARE validJSONCount int;
DECLARE result varchar(300);
SET notNullCount = (SELECT count(*) FROM DB_NAME.TABLE_NAME WHERE JSON_COLUMN IS NOT NULL);
set validJSONCount = (SELECT count(*) FROM DB_NAME.TABLE_NAME WHERE JSON_VALID(JSON_COLUMN) > 0);
CASE
WHEN (validJSONCount = notNullCount) THEN
SET result = CONCAT('VALID JSON COUNT: ', validJSONCount)
ELSE
SET result = CONCAT('INVALID JSON COUNT: ', (notNullCount - validJSONCount))
END;
RETURN result;
END //
DELIMITER ;
When I try to run this code, I get the following error message:
"Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ELSE SET result = CONCAT('INVALID JSON COUNT: ', (notNullCount - validJSONC' at line 14"
Any thoughts on how I might improve this code? Thanks!
Since MySQL 5.7 you have a pretty and simple function for this:
JSON_VALID(value)
Returns 0 or 1 to indicate whether a value is valid JSON. Returns NULL if the argument is NULL.
https://dev.mysql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-valid
You're missing a couple of ; and to end the case it should be END CASE.
DELIMITER //
CREATE FUNCTION CHECKJSON( DB_NAME varchar(255), TABLE_NAME varchar(255), JSON_COLUMN varchar(255))
RETURNS varchar(300)
BEGIN
DECLARE notNullCount int;
DECLARE validJSONCount int;
DECLARE result varchar(300);
SET notNullCount = (SELECT count(*) FROM DB_NAME.TABLE_NAME WHERE JSON_COLUMN IS NOT NULL);
set validJSONCount = (SELECT count(*) FROM DB_NAME.TABLE_NAME WHERE JSON_VALID(JSON_COLUMN) > 0);
CASE
WHEN (validJSONCount = notNullCount) THEN
SET result = CONCAT('VALID JSON COUNT: ', validJSONCount) ;
ELSE
SET result = CONCAT('INVALID JSON COUNT: ', (notNullCount - validJSONCount)) ;
END CASE;
RETURN result;
END //
DELIMITER ;

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

mysql procedure syntax error

I get an error by sending the following query (MYSQL 5.0):
DELIMITER //
CREATE PROCEDURE relationTable ()
BEGIN
DECLARE articlecount int;
DECLARE keywordcount int;
DECLARE articlehits int;
DECLARE ac int DEFAULT 0;
DECLARE kc int;
DECLARE articleid int;
DECLARE word varchar(100);
DECLARE word_id int;
SET articlehits = 0;
SET articlecount = (SELECT count(id) from articles);
SET keywordcount = (SELECT count(id) from keywords);
outerloop: WHILE (ac < articlecount) DO
SET kc = 0;
SET articleid = (SELECT id from articles LIMIT 1 OFFSET ac);
innerloop: WHILE (kc < keywordcount) DO
IF (articlehits < 5) THEN
SELECT keyword, id INTO word, word_id from keywords LIMIT 1 OFFSET kc;
IF (0 < (SELECT COUNT(id) from articles WHERE id=articleid AND CONCAT(title, " ",text) REGEXP word)) THEN
INSERT INTO articles (id, articleID, keywordID, type) VALUES(NULL, articleid, word_id, 'type1');
SET articlehits = articlehits + 1;
END IF;
SET kc = kc + 1;
ELSE
SET kc = keywordcount;
END IF;
END WHILE innerloop;
SET ac = ac + 1;
END WHILE outerloop;
END;
//
DELIMITER ;
This produces the following error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right
syntax to use near 'LIMIT 1 OFFSET ac); innerloop: WHILE (kc <
keywordcount) DO TO word, word_id from' at line 15
Any idea why this happens?
(Wrote this to create a relation table between articles and keywords, to enable smart-links in article view.)
Try to remove the while labels:
WHILE (ac < articlecount) DO
SET kc = 0;
SET articleid = (SELECT id from articles LIMIT 1 OFFSET ac);
WHILE (kc < keywordcount) DO
IF (articlehits < 5) THEN
SELECT keyword, id INTO word, word_id from keywords LIMIT 1 OFFSET kc;
IF (0 < (SELECT COUNT(id) from articles WHERE id=articleid AND CONCAT(title, " ",text) REGEXP word)) THEN
INSERT INTO articles (id, articleID, keywordID, type) VALUES(NULL, articleid, word_id, 'type1');
SET articlehits = articlehits + 1;
END IF;
SET kc = kc + 1;
ELSE
SET kc = keywordcount;
END IF;
END WHILE;
SET ac = ac + 1;
END WHILE;
MySQL has connection-specific user-defined variables of the form #varname and declared procedure variables of the type you are using in your code sample. In my experience with procedures, sometimes only one of the types is allowed, and if I recall correctly, one of those situations may be when SELECTing INTO. You might try using user-defined variables here, as follows:
SET articleid = (SELECT id from articles LIMIT 1 OFFSET ac);
innerloop: WHILE (kc < keywordcount) DO
IF (articlehits < 5) THEN
SELECT keyword, id INTO #word, #word_id from keywords LIMIT 1 OFFSET kc;
Just an idea.
One problem may be the SET acticleid = (SELECT...). Try with SELECT .. INTO:
SELECT id INTO #articleid FROM articles LIMIT 1 OFFSET ac;
Variable LIMIT in stored procedures is only supported in new MySQL versions. Note that since you dont have an ORDER BY you will get a random row. It looks like you want to use a CURSOR instead. See docs.
At the risk of seeming over-critical, I believe you should rewrite this procedure to use cursors for traversing your databases, instead of individual selects with LIMIT.
see Cursors in MySQL Docs
Thank for your help so far.
The idea of Tom Haws proved to be correct. The variables for a SELECT INTO statement have to be user-defined.
I edited my code to use cursors, and user-defined variables as followed:
delimiter //
CREATE PROCEDURE relationTable ()
BEGIN
DECLARE articlehits int;
DECLARE looparticles int DEFAULT TRUE;
DECLARE loopwords int DEFAULT TRUE;
DECLARE done INT DEFAULT FALSE;
DECLARE keywordcursor CURSOR FOR SELECT keyword, id FROM keywords;
DECLARE articlecursor CURSOR FOR SELECT id FROM articles;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN articlecursor;
WHILE (looparticles) DO
FETCH articlecursor INTO #articleid;
IF done THEN SET looparticles = FALSE;
ELSE
SET articlehits = 0;
OPEN keywordcursor;
WHILE (loopwords) DO
FETCH keywordcursor INTO #word, #wordid;
IF (articlehits < 5) AND NOT done THEN
IF (0 < (SELECT COUNT(id) FROM articles WHERE id=#articleid AND CONCAT(title, " ", text) REGEXP #word)) THEN
INSERT INTO keyword_article_rel (id, meldungID, wordID) VALUES(NULL, #articleid, #wordid);
SET articlehits = articlehits + 1;
END IF;
ELSE
SET loopwords = FALSE;
CLOSE keywordcursor;
SET done = FALSE;
END IF;
END WHILE;
END IF;
END WHILE;
CLOSE articlecursor;
END;
//
delimiter ;
And now I get an other error that I really can't explain:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN articlecursor; W' at line 6
This error confuses me because it can't have a problem with the handler. The handler is declared as in the example of the mysql-documentation. Could the problem be that I can't create two cursors like this?