Search code examples
sqlmysql-workbenchworkbench

Error 1064 when i creating my Procedure Statement in mySQL workbench


This is my code for the Procedure statement that i think is working correctly but i can not run it because i keep getting this error: Error Code: 1064. 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 ');     -- issue the new loan.  INSERT INTO loan (<code>code</code>, <code>no</code>, taken, due)    VA' at line 70Error Code: 1064. 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 '); -- issue the new loan. INSERT INTO loan (code, no, taken, due) VA' at line 70

I try to find ways to fix it but i didn't find anything. Can anyone else see if i wrote something wrong or i have made any mistakes in my code somewhere that i can not see? The error is sending me to the line 70 but also the FETCH NEXT FROM copy_c INTO copy_code; is telling me that the FROM is not at the correct position. Also i include my comments for more easier way of reading this code.

DELIMITER $$

          CREATE PROCEDURE `new_loan` (IN book_isbn CHAR(17), IN student_no INT)

          BEGIN

        -- search for the copy of the book and test for loan record in loan table.
        DECLARE copy_code, loan_test INT;

        -- test for successful loan and for end of cursor.
        DECLARE inserted, complete BOOLEAN;


        -- the duration date and current date for new loan issue and number of days for the new loan.
        DECLARE due, cur DATE;
        DECLARE copy_dur TINYINT;

        -- test if students can loan books.
    DECLARE embargo_status BIT(1) DEFAULT b'1';

    -- cursor for copy codes based on isbn.
    DECLARE copy_c CURSOR FOR
        SELECT `code`
        FROM copy
        WHERE isbn = book_isbn;

        DECLARE CONTINUE HANDLER FOR NOT FOUND
            SET complete = TRUE;


        OPEN copy_c;

        -- get student embargo status.
        SET embargo_status = (SELECT embargo 
                    FROM student
                    WHERE `no` = student_no);

        SELECT embargo_status;

        -- check if the student is valid or embargo is no, if not report a message.
        IF (embargo_status IS NULL OR embargo_status = b'1') THEN
            SIGNAL SQLSTATE '45000'
                SET MESSAGE_TEXT = 'The student is not valid or has embargo!';
        END IF;

        SET inserted = FALSE;
        SET copy_code = 0;

        -- loop through copies to see when that is available.
        copy_codes: LOOP
        FETCH NEXT FROM copy_c INTO copy_code;

        IF complete THEN 
            SIGNAL SQLSTATE '45000'
                SET MESSAGE_TEXT = 'We looped to end and found nothing!';
        END IF;

        -- if a copy is available then loan_test will be null.  
        -- if return is null the book is out on loan and a non null value will be returned to loan_test.
        SET loan_test = (SELECT `code` FROM loan
                    WHERE (`code` = copy_code) AND (`return` IS NULL));

        -- if a copy is available loan_test will be null.  
    -- A null value implies that the copy had a one or many records in loan with a non null return or the copy was never out on loan.
        IF (loan_test IS NULL) THEN     
            SET cur = CURRENT_DATE();
            SET copy_dur = (SELECT duration 
                     FROM copy
                     WHERE `code` = copy_code);

        -- calculate due date.
        SET due = DATE_ADD (cur, INTERVAL copy_dur DAY);


        -- issue the new loan.
        INSERT INTO loan (`code`, `no`, taken, due)
                VALUES (copy_code, student_no, cur, due);

        SET inserted = TRUE;

        LEAVE copy_codes;

        END IF;

        END LOOP;

        CLOSE copy_c;

        -- inform users of a failed loan.
        IF (inserted = FALSE) THEN 
            SIGNAL SQLSTATE '45000'
                SET MESSAGE_TEXT = 'No currently available copies or book does not exist! '; 
        END IF;

    END$$

    DELIMITER ;

Solution

  • MySQL Workbench gives you an error message with details. Didn't you see that? Actually, it gives you 2 errors, but the first one (about FETCH NEXT) is a bug in the WB syntax checker and will be fixed in the next release.

    The second one says:

    "DATE_ADD" is not valid at this position, expecting a complete function call or other expression.

    Which much better describes what is wrong than those ugly error messages from MySQL (or MariaDB for that matter). When you look at that call you see there's a space before the opening parenthesis, which changes the meaning due to SQL mode IGNORE_SPACE. Remove the space char and your SP will be accepted.