0

I have a table, book_chapters given with following sample data;

chapter_name | chapter_number
 A Dead Man  | LVI
 Imitation   | IX

As seen the chapter number are given in Roman numerals. The goal is to get the output in the following form;

chapter_name|chapter_number| cnt
A Dead Man  | LVI          | 56
Imitation   | IX           | 9

Here is my attempt at the code;

DELIMITER $$
DROP FUNCTION IF EXISTS primitive $$



CREATE FUNCTION primitive (r VARCHAR(15)) RETURNS INT DETERMINISTIC
BEGIN
     DECLARE result INT;

     IF r = 'I' THEN
       SET result =1;
        
    ELSEIF r = 'V' THEN
       SET result =5;
       
    ELSEIF r='X' THEN
       SET result=10;
       
    ELSEIF r = 'L' THEN 
        SET result= 50;
         
    ELSEIF r = 'C' THEN 
        SET result = 100; 
        
    ELSEIF r = 'D' THEN 
        SET result =500; 
        
    ELSEIF r = 'M' THEN 
        SET result = 1000;
    END IF;
    RETURN result;
END$$
DELIMITER;
DROP FUNCTION IF EXISTS chapter ;
DELIMITER $$ 


CREATE FUNCTION chapter(chaptername VARCHAR(20)) RETURNS INT DETERMINISTIC
BEGIN
     DECLARE val INT;
     DECLARE curr INT;
     DECLARE idx VARCHAR(20);
     DECLARE chapternum VARCHAR(20);
     SET val=0;
     SET curr=0;
     SET idx='';
     SET chapternum= chaptername;

     
     WHILE CHAR_LENGTH(chapternum)>0 DO
           SET idx=RIGHT(chapternum,1); /*traverse from the right side*/
           SET curr=primitive(idx);
           IF curr>=val THEN
              SET val= curr+val;
           ELSE
              SET val= val-curr;
           END IF;
           SET chapternum=LEFT(chapternum,CHAR_LENGTH(chapternum)-1);/*delete the rightmost char*/
     END WHILE;
     RETURN val;
END$$
DELIMITER;
DROP PROCEDURE IF EXISTS sortBookChapters;
DELIMITER $$

     
CREATE PROCEDURE sortBookChapters()
BEGIN 
 WITH CTE1 AS(
     
     SELECT chapter_name ,
            chapter_number AS chaptername
     FROM book_chapters
 )   
SELECT chapter_name, chaptername,chapter(chaptername) AS cnt
FROM CTE1;   

END $$

My logic of converting roman to decimal seems to be working, will be happy to get some feedback if there are errors. But I am getting following syntax error right now;

ERROR 1064 (42000) in the pre-written template: 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 ';

CREATE FUNCTION chapter(chaptername VARCHAR(20)) RETURNS INT DETERMINISTIC B' at line 27

Can I get some help to debug this syntax error?

2
  • 1
    Normalise your data. Store numbers as integers. Display them however you like. Commented Oct 4, 2020 at 4:54
  • And just sayin'... planet.mysql.com/entry/?id=30330 Commented Oct 4, 2020 at 4:58

2 Answers 2

1

You gotta put your nonstandard delimiter ($$) after every stored function declaration.

You only have it after the last one in your example code.

And, it's IF ... ELSEIF ... ELSEIF ... END IF;. Don't use ELSE IF.

Sign up to request clarification or add additional context in comments.

2 Comments

Appreciate your reply. I tried to put the delimiter after every stored function defn., as suggested. Please see the code above. In that case, I got new error; ` ERROR 1064 (42000) in the pre-written template: 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 '' at line 27`. Can you kindly advise?
Than ks for the feedback. Please see the edited code. But this is giving. a new error message; ERROR 1065 (42000) in the pre-written template: Query was empty. Is there a way to debug it? Help is appreciated
0

No need to change the Delimiter.

This is your script running without errors:

DELIMITER $$

DROP FUNCTION IF EXISTS primitive $$

CREATE FUNCTION primitive (r VARCHAR(15)) RETURNS INT DETERMINISTIC
BEGIN
     DECLARE result INT;

     IF r = 'I' THEN
       SET result =1;
        
    ELSEIF r = 'V' THEN
       SET result =5;
       
    ELSEIF r='X' THEN
       SET result=10;
       
    ELSEIF r = 'L' THEN 
        SET result= 50;
         
    ELSEIF r = 'C' THEN 
        SET result = 100; 
        
    ELSEIF r = 'D' THEN 
        SET result =500; 
        
    ELSEIF r = 'M' THEN 
        SET result = 1000;
    END IF;
    RETURN result;
END$$

DROP FUNCTION IF EXISTS chapter $$

CREATE FUNCTION chapter(chaptername VARCHAR(20)) RETURNS INT DETERMINISTIC
BEGIN
     DECLARE val INT;
     DECLARE curr INT;
     DECLARE idx VARCHAR(20);
     DECLARE chapternum VARCHAR(20);
     SET val=0;
     SET curr=0;
     SET idx='';
     SET chapternum= chaptername;

     
     WHILE CHAR_LENGTH(chapternum)>0 DO
           SET idx=RIGHT(chapternum,1); /*traverse from the right side*/
           SET curr=primitive(idx);
           IF curr>=val THEN
              SET val= curr+val;
           ELSE
              SET val= val-curr;
           END IF;
           SET chapternum=LEFT(chapternum,CHAR_LENGTH(chapternum)-1);/*delete the rightmost char*/
     END WHILE;
     RETURN val;
END$$

DROP PROCEDURE IF EXISTS sortBookChapters $$
     
CREATE PROCEDURE sortBookChapters()
BEGIN 
     WITH CTE1 AS(
         
         SELECT chapter_name ,
                chapter_number AS chaptername
         FROM book_chapters
     )   
    SELECT chapter_name, chaptername,chapter(chaptername) AS cnt
    FROM CTE1;   
    
END $$
DELIMITER ;

3 Comments

@L Q. Appreciate your reply. But isn't that's what the mysql documentation says, to change the delimiters. Being a beginner, I am trying to follow this link on how to implement stored functions in MySql. mysqltutorial.org/mysql-stored-function. Can you kindly provide thoughts?
The standard MySQL delimiter is (;) which is also used to end the statements in Triggers, Functions and Procedures, so for the client to send the create function block complete as one to the server you should change the delimiter (if you are sending a script to create triggers, stored functions or procedures) but you need to change it only once at the beginning and set it back at the end of the script, I've updated your script in my answer.
@L Q Apologies I could not reply earlier. As suggested, I used the above provided code, change delimiter at the start and set it back at the end. This has provided a new error message; ERROR 1064 (42000) in the pre-written template: 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 '$$ delimiter' at line 1. I'm not being able to comprehend, at which line its referring to. I want to clarify that MySql version is 8.0.21. Is it possible, you can provide some insight.your advice is appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.