web-dev-qa-db-fra.com

Mysql Procédure stockée avec curseur

Problème de curseur Mysql?

J'ai écrit une procédure stockée qui voyagera le dossier d'une table et l'insérera dans 2-3 tables différentes en utilisant des instructions d'insertion.

Le problème est que je vérifie si l'enregistrement n'existe pas dans la table1, puis j'insère l'enregistrement de tentable dans la table1, la table2 séquentiellement, mais la condition a un problème, je ne sais pas si cela va toujours dans une autre partie.

L'échantillon de code est le suivant:

CREATE PROCEDURE `insertData`(In clientNo INT,In usedID INT)
BEGIN

declare mame varchar(100);
declare address varchar(100);
declare city varchar(50);
declare IdentityNO1 varchar(20)


declare cur1 cursor for select * from temptable;
declare continue handler for not found set done=1;

SET @clientNo = clientNO;
SET @userID = userID;


    set done = 0;
    open cur1;
    igmLoop: loop
        fetch cur1 into Name,Address,City,IdentityNO1,clientNo;
        if done = 1 then leave igmLoop; end if;

        //If no record exists in some records table1,table2.
        IF ( (SELECT COUNT(*) FROM table1 
               WHERE IndentityNo=IdentityNo1 
                 AND clientNo=@clientNo) < = 0)
              INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1);
              INSERT INTO table2 (Address,City) VALUES(address,city);
        ELSE
              INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
              VALUES(name,address,city,IdentityNo1);
    end loop igmLoop;
    close cur1;
END
9
user3122164

Il n'y a ni THEN ni END IF mots-clés, la procédure ne peut pas être compilée.
Vérifiez ce lien pour la syntaxe appropriée de l'instruction IF: http://dev.mysql.com/doc/refman/5.7/en/if.html

Utilisez l'opérateur EXIST au lieu de (SELECT count(*)... ) <=0,
lisez ce lien pour en connaître la raison: http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends .aspx

IF    EXISTS(  
               SELECT null FROM table1 
               WHERE IndentityNo=IdentityNo1 
                 AND clientNo=@clientNo
      )
THEN
              INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1);
              INSERT INTO table2 (Address,City) VALUES(address,city);
ELSE
              INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
              VALUES(name,address,city,IdentityNo1);
END IF;


Je recommande d'utiliser certains préfixes pour les arguments de procédure et les noms de variable pour éviter toute ambiguïté, par exemple, utilisez p_ pour les paramètres et v_ pour les variables. Il est difficile de deviner, en regardant ce code, quel nom est un nom de colonne, une variable ou un paramètre de procédure. Cela peut entraîner des erreurs et des erreurs.

Évitez d'utiliser SELECT * - ce code échouera si quelqu'un change la structure de la table. Liste explicitement les colonnes requises dans la déclaration du curseur:

declare cur1 cursor for 
        select name,Address,City,IdentityNO,clientNo
        from temptable;

La procédure corrigée pourrait ressembler à ceci:

CREATE PROCEDURE `insertData`(In p_clientNo INT,In p_usedID INT)
BEGIN

declare v_name varchar(100);
declare v_address varchar(100);
declare v_city varchar(50);
declare v_IdentityNO varchar(20)
declare v_clientNo int


declare cur1 cursor for 
        select name,Address,City,IdentityNO,clientNo
        from temptable;
declare continue handler for not found set done=1;

    set done = 0;
    open cur1;
    igmLoop: loop
        fetch cur1 into v_name,v_Address,v_City,v_IdentityNO,v_clientNo;
        if done = 1 then leave igmLoop; end if;

        //If no record exists in some records table1,table2.
        IF  EXISTS(  SELECT 1 FROM table1 
                     WHERE IndentityNo = v_IdentityNo 
                       AND clientNo = v_clientNo)
              INSERT INTO table1 (Name,IdentityNO) VALUES (v_name,v_IdentityNO);
              INSERT INTO table2 (Address,City) VALUES(v_address,v_city);
        ELSE
              INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
              VALUES(v_name,v_address,v_city,v_IdentityNo);
        END IF;
    end loop igmLoop;
    close cur1;
END
18
krokodilko