Mysql if not exists gives my an error in a stored-procedure












0















I have the following stored procedure in phpmyadmin using mysql:



CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`(IN `patient_street` VARCHAR(128), IN 
`patient_city` VARCHAR(45), IN `patient_post_code` VARCHAR(45), IN `patient_state_or_province` VARCHAR(45), IN `patient_country` VARCHAR(45))
NOT DETERMINISTIC NO SQL SQL SECURITY
DEFINER
BEGIN
IF NOT EXISTS (SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country)
THEN
BEGIN
INSERT INTO address (street, city, post_code, state_or_province, country) VALUES (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
SELECT LAST_INSERT_ID();
END;
ELSE
BEGIN
SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country
END;
END IF;
END;


However, I got 2 errors in IF NOT EXISTS:




  1. Unrecognized keyword. (near IF NOT EXISTS)

  2. Unexpected token. (near()










share|improve this question

























  • Every if must have a then and an end if. Your insert statement doesn't make a lot of sense either , you cannot mix insert...values with a select like this.And mysql does not require a begin end block in an if end if block.

    – P.Salmon
    Nov 21 '18 at 15:30













  • @P.Salmon I want to check firstly whether the address is already stored in my db otherwise store it and get it's corresponding id.

    – zinon
    Nov 21 '18 at 15:32











  • You probably need to terminate the insert..values statement.

    – P.Salmon
    Nov 21 '18 at 15:34











  • @P.Salmon I updated my code. Still I get the same error.

    – zinon
    Nov 21 '18 at 15:37











  • You really should remove the requirement to terminate statements - you are missing ; after end if and all end blocks also you haven't shown that you are resetting delimiters before and after procedure creation code (which you also haven't shown).

    – P.Salmon
    Nov 21 '18 at 15:47
















0















I have the following stored procedure in phpmyadmin using mysql:



CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`(IN `patient_street` VARCHAR(128), IN 
`patient_city` VARCHAR(45), IN `patient_post_code` VARCHAR(45), IN `patient_state_or_province` VARCHAR(45), IN `patient_country` VARCHAR(45))
NOT DETERMINISTIC NO SQL SQL SECURITY
DEFINER
BEGIN
IF NOT EXISTS (SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country)
THEN
BEGIN
INSERT INTO address (street, city, post_code, state_or_province, country) VALUES (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
SELECT LAST_INSERT_ID();
END;
ELSE
BEGIN
SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country
END;
END IF;
END;


However, I got 2 errors in IF NOT EXISTS:




  1. Unrecognized keyword. (near IF NOT EXISTS)

  2. Unexpected token. (near()










share|improve this question

























  • Every if must have a then and an end if. Your insert statement doesn't make a lot of sense either , you cannot mix insert...values with a select like this.And mysql does not require a begin end block in an if end if block.

    – P.Salmon
    Nov 21 '18 at 15:30













  • @P.Salmon I want to check firstly whether the address is already stored in my db otherwise store it and get it's corresponding id.

    – zinon
    Nov 21 '18 at 15:32











  • You probably need to terminate the insert..values statement.

    – P.Salmon
    Nov 21 '18 at 15:34











  • @P.Salmon I updated my code. Still I get the same error.

    – zinon
    Nov 21 '18 at 15:37











  • You really should remove the requirement to terminate statements - you are missing ; after end if and all end blocks also you haven't shown that you are resetting delimiters before and after procedure creation code (which you also haven't shown).

    – P.Salmon
    Nov 21 '18 at 15:47














0












0








0








I have the following stored procedure in phpmyadmin using mysql:



CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`(IN `patient_street` VARCHAR(128), IN 
`patient_city` VARCHAR(45), IN `patient_post_code` VARCHAR(45), IN `patient_state_or_province` VARCHAR(45), IN `patient_country` VARCHAR(45))
NOT DETERMINISTIC NO SQL SQL SECURITY
DEFINER
BEGIN
IF NOT EXISTS (SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country)
THEN
BEGIN
INSERT INTO address (street, city, post_code, state_or_province, country) VALUES (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
SELECT LAST_INSERT_ID();
END;
ELSE
BEGIN
SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country
END;
END IF;
END;


However, I got 2 errors in IF NOT EXISTS:




  1. Unrecognized keyword. (near IF NOT EXISTS)

  2. Unexpected token. (near()










share|improve this question
















I have the following stored procedure in phpmyadmin using mysql:



CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`(IN `patient_street` VARCHAR(128), IN 
`patient_city` VARCHAR(45), IN `patient_post_code` VARCHAR(45), IN `patient_state_or_province` VARCHAR(45), IN `patient_country` VARCHAR(45))
NOT DETERMINISTIC NO SQL SQL SECURITY
DEFINER
BEGIN
IF NOT EXISTS (SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country)
THEN
BEGIN
INSERT INTO address (street, city, post_code, state_or_province, country) VALUES (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
SELECT LAST_INSERT_ID();
END;
ELSE
BEGIN
SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country
END;
END IF;
END;


However, I got 2 errors in IF NOT EXISTS:




  1. Unrecognized keyword. (near IF NOT EXISTS)

  2. Unexpected token. (near()







mysql stored-procedures phpmyadmin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 15:57







zinon

















asked Nov 21 '18 at 15:26









zinonzinon

1,61243569




1,61243569













  • Every if must have a then and an end if. Your insert statement doesn't make a lot of sense either , you cannot mix insert...values with a select like this.And mysql does not require a begin end block in an if end if block.

    – P.Salmon
    Nov 21 '18 at 15:30













  • @P.Salmon I want to check firstly whether the address is already stored in my db otherwise store it and get it's corresponding id.

    – zinon
    Nov 21 '18 at 15:32











  • You probably need to terminate the insert..values statement.

    – P.Salmon
    Nov 21 '18 at 15:34











  • @P.Salmon I updated my code. Still I get the same error.

    – zinon
    Nov 21 '18 at 15:37











  • You really should remove the requirement to terminate statements - you are missing ; after end if and all end blocks also you haven't shown that you are resetting delimiters before and after procedure creation code (which you also haven't shown).

    – P.Salmon
    Nov 21 '18 at 15:47



















  • Every if must have a then and an end if. Your insert statement doesn't make a lot of sense either , you cannot mix insert...values with a select like this.And mysql does not require a begin end block in an if end if block.

    – P.Salmon
    Nov 21 '18 at 15:30













  • @P.Salmon I want to check firstly whether the address is already stored in my db otherwise store it and get it's corresponding id.

    – zinon
    Nov 21 '18 at 15:32











  • You probably need to terminate the insert..values statement.

    – P.Salmon
    Nov 21 '18 at 15:34











  • @P.Salmon I updated my code. Still I get the same error.

    – zinon
    Nov 21 '18 at 15:37











  • You really should remove the requirement to terminate statements - you are missing ; after end if and all end blocks also you haven't shown that you are resetting delimiters before and after procedure creation code (which you also haven't shown).

    – P.Salmon
    Nov 21 '18 at 15:47

















Every if must have a then and an end if. Your insert statement doesn't make a lot of sense either , you cannot mix insert...values with a select like this.And mysql does not require a begin end block in an if end if block.

– P.Salmon
Nov 21 '18 at 15:30







Every if must have a then and an end if. Your insert statement doesn't make a lot of sense either , you cannot mix insert...values with a select like this.And mysql does not require a begin end block in an if end if block.

– P.Salmon
Nov 21 '18 at 15:30















@P.Salmon I want to check firstly whether the address is already stored in my db otherwise store it and get it's corresponding id.

– zinon
Nov 21 '18 at 15:32





@P.Salmon I want to check firstly whether the address is already stored in my db otherwise store it and get it's corresponding id.

– zinon
Nov 21 '18 at 15:32













You probably need to terminate the insert..values statement.

– P.Salmon
Nov 21 '18 at 15:34





You probably need to terminate the insert..values statement.

– P.Salmon
Nov 21 '18 at 15:34













@P.Salmon I updated my code. Still I get the same error.

– zinon
Nov 21 '18 at 15:37





@P.Salmon I updated my code. Still I get the same error.

– zinon
Nov 21 '18 at 15:37













You really should remove the requirement to terminate statements - you are missing ; after end if and all end blocks also you haven't shown that you are resetting delimiters before and after procedure creation code (which you also haven't shown).

– P.Salmon
Nov 21 '18 at 15:47





You really should remove the requirement to terminate statements - you are missing ; after end if and all end blocks also you haven't shown that you are resetting delimiters before and after procedure creation code (which you also haven't shown).

– P.Salmon
Nov 21 '18 at 15:47












1 Answer
1






active

oldest

votes


















1














Personally, if I had a requirement to write a procedure that performed the specified operations, and returned a resultset, I'd write it like this:



DELIMITER $$

CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`
(IN `patient_street` VARCHAR(128)
,IN `patient_city` VARCHAR(45)
,IN `patient_post_code` VARCHAR(45)
,IN `patient_state_or_province` VARCHAR(45)
,IN `patient_country` VARCHAR(45)
)
NOT DETERMINISTIC SQL SECURITY DEFINER
BEGIN
DECLARE li_address_id BIGINT DEFAULT NULL;
-- check for existing row and get address_id
SELECT a.address_id
INTO li_address_id
FROM address a
WHERE a.street = patient_street
AND a.city = patient_city
AND a.post_code = patient_post_code
AND a.country = patient_country
LIMIT 1 ;
-- if we didn't find a matching row
IF li_address_id IS NULL THEN
-- add a row and get the new address_id
INSERT INTO address (street, city, post_code, state_or_province, country) VALUES
(patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
SELECT LAST_INSERT_ID() INTO li_address_id;
END IF;

-- return address_id (either found existing row, or newly added row) as a resultset
SELECT li_address_id AS address_id;
END$$

DELIMITER ;




If a row exists, we don't need to run two SELECT statements. We can do the check for the row AND get the address_id with a single SELECT.



If we didn't get a matching row, then we insert a row, and retrieve the auto-increment id.



In either case (found row, or added row), return the address_id as a resultset. Again, we can do that with a single SELECT statement, rather than two different statements.



To me, it makes more sense to limit the number of places we are returning resultsets, and limit the number of times we query the database.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415304%2fmysql-if-not-exists-gives-my-an-error-in-a-stored-procedure%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Personally, if I had a requirement to write a procedure that performed the specified operations, and returned a resultset, I'd write it like this:



    DELIMITER $$

    CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`
    (IN `patient_street` VARCHAR(128)
    ,IN `patient_city` VARCHAR(45)
    ,IN `patient_post_code` VARCHAR(45)
    ,IN `patient_state_or_province` VARCHAR(45)
    ,IN `patient_country` VARCHAR(45)
    )
    NOT DETERMINISTIC SQL SECURITY DEFINER
    BEGIN
    DECLARE li_address_id BIGINT DEFAULT NULL;
    -- check for existing row and get address_id
    SELECT a.address_id
    INTO li_address_id
    FROM address a
    WHERE a.street = patient_street
    AND a.city = patient_city
    AND a.post_code = patient_post_code
    AND a.country = patient_country
    LIMIT 1 ;
    -- if we didn't find a matching row
    IF li_address_id IS NULL THEN
    -- add a row and get the new address_id
    INSERT INTO address (street, city, post_code, state_or_province, country) VALUES
    (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
    SELECT LAST_INSERT_ID() INTO li_address_id;
    END IF;

    -- return address_id (either found existing row, or newly added row) as a resultset
    SELECT li_address_id AS address_id;
    END$$

    DELIMITER ;




    If a row exists, we don't need to run two SELECT statements. We can do the check for the row AND get the address_id with a single SELECT.



    If we didn't get a matching row, then we insert a row, and retrieve the auto-increment id.



    In either case (found row, or added row), return the address_id as a resultset. Again, we can do that with a single SELECT statement, rather than two different statements.



    To me, it makes more sense to limit the number of places we are returning resultsets, and limit the number of times we query the database.






    share|improve this answer




























      1














      Personally, if I had a requirement to write a procedure that performed the specified operations, and returned a resultset, I'd write it like this:



      DELIMITER $$

      CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`
      (IN `patient_street` VARCHAR(128)
      ,IN `patient_city` VARCHAR(45)
      ,IN `patient_post_code` VARCHAR(45)
      ,IN `patient_state_or_province` VARCHAR(45)
      ,IN `patient_country` VARCHAR(45)
      )
      NOT DETERMINISTIC SQL SECURITY DEFINER
      BEGIN
      DECLARE li_address_id BIGINT DEFAULT NULL;
      -- check for existing row and get address_id
      SELECT a.address_id
      INTO li_address_id
      FROM address a
      WHERE a.street = patient_street
      AND a.city = patient_city
      AND a.post_code = patient_post_code
      AND a.country = patient_country
      LIMIT 1 ;
      -- if we didn't find a matching row
      IF li_address_id IS NULL THEN
      -- add a row and get the new address_id
      INSERT INTO address (street, city, post_code, state_or_province, country) VALUES
      (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
      SELECT LAST_INSERT_ID() INTO li_address_id;
      END IF;

      -- return address_id (either found existing row, or newly added row) as a resultset
      SELECT li_address_id AS address_id;
      END$$

      DELIMITER ;




      If a row exists, we don't need to run two SELECT statements. We can do the check for the row AND get the address_id with a single SELECT.



      If we didn't get a matching row, then we insert a row, and retrieve the auto-increment id.



      In either case (found row, or added row), return the address_id as a resultset. Again, we can do that with a single SELECT statement, rather than two different statements.



      To me, it makes more sense to limit the number of places we are returning resultsets, and limit the number of times we query the database.






      share|improve this answer


























        1












        1








        1







        Personally, if I had a requirement to write a procedure that performed the specified operations, and returned a resultset, I'd write it like this:



        DELIMITER $$

        CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`
        (IN `patient_street` VARCHAR(128)
        ,IN `patient_city` VARCHAR(45)
        ,IN `patient_post_code` VARCHAR(45)
        ,IN `patient_state_or_province` VARCHAR(45)
        ,IN `patient_country` VARCHAR(45)
        )
        NOT DETERMINISTIC SQL SECURITY DEFINER
        BEGIN
        DECLARE li_address_id BIGINT DEFAULT NULL;
        -- check for existing row and get address_id
        SELECT a.address_id
        INTO li_address_id
        FROM address a
        WHERE a.street = patient_street
        AND a.city = patient_city
        AND a.post_code = patient_post_code
        AND a.country = patient_country
        LIMIT 1 ;
        -- if we didn't find a matching row
        IF li_address_id IS NULL THEN
        -- add a row and get the new address_id
        INSERT INTO address (street, city, post_code, state_or_province, country) VALUES
        (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
        SELECT LAST_INSERT_ID() INTO li_address_id;
        END IF;

        -- return address_id (either found existing row, or newly added row) as a resultset
        SELECT li_address_id AS address_id;
        END$$

        DELIMITER ;




        If a row exists, we don't need to run two SELECT statements. We can do the check for the row AND get the address_id with a single SELECT.



        If we didn't get a matching row, then we insert a row, and retrieve the auto-increment id.



        In either case (found row, or added row), return the address_id as a resultset. Again, we can do that with a single SELECT statement, rather than two different statements.



        To me, it makes more sense to limit the number of places we are returning resultsets, and limit the number of times we query the database.






        share|improve this answer













        Personally, if I had a requirement to write a procedure that performed the specified operations, and returned a resultset, I'd write it like this:



        DELIMITER $$

        CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`
        (IN `patient_street` VARCHAR(128)
        ,IN `patient_city` VARCHAR(45)
        ,IN `patient_post_code` VARCHAR(45)
        ,IN `patient_state_or_province` VARCHAR(45)
        ,IN `patient_country` VARCHAR(45)
        )
        NOT DETERMINISTIC SQL SECURITY DEFINER
        BEGIN
        DECLARE li_address_id BIGINT DEFAULT NULL;
        -- check for existing row and get address_id
        SELECT a.address_id
        INTO li_address_id
        FROM address a
        WHERE a.street = patient_street
        AND a.city = patient_city
        AND a.post_code = patient_post_code
        AND a.country = patient_country
        LIMIT 1 ;
        -- if we didn't find a matching row
        IF li_address_id IS NULL THEN
        -- add a row and get the new address_id
        INSERT INTO address (street, city, post_code, state_or_province, country) VALUES
        (patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
        SELECT LAST_INSERT_ID() INTO li_address_id;
        END IF;

        -- return address_id (either found existing row, or newly added row) as a resultset
        SELECT li_address_id AS address_id;
        END$$

        DELIMITER ;




        If a row exists, we don't need to run two SELECT statements. We can do the check for the row AND get the address_id with a single SELECT.



        If we didn't get a matching row, then we insert a row, and retrieve the auto-increment id.



        In either case (found row, or added row), return the address_id as a resultset. Again, we can do that with a single SELECT statement, rather than two different statements.



        To me, it makes more sense to limit the number of places we are returning resultsets, and limit the number of times we query the database.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 16:34









        spencer7593spencer7593

        85.7k108097




        85.7k108097
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415304%2fmysql-if-not-exists-gives-my-an-error-in-a-stored-procedure%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Hercules Kyvelos

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud