避免存储过程中重复条目的逻辑条件

时间:2014-04-11 11:24:08

标签: mysql stored-procedures

我有以下存储过程。我尝试将其管理变量等于1的表usuaris中的用户插入到存储过程使用作为参数传递的名称(nombre varchar(50))创建的表中。

当调用该程序时,它会复制用户' mary'与id 4.我已经尝试了几种方法来实现逻辑条件以避免重复,但是,我仍然缺少一些东西而我无法获得所需的东西结果。在下面的代码中,插入之前的逻辑条件是我尝试过的最后一件事。有什么想法吗?

感谢。

 CREATE DEFINER=`root`@`localhost` PROCEDURE `createNewtable`(nombre varchar(50))
 BEGIN

 /*variable declaration*/

 declare centinela int ;
 declare id1 int ;
 declare nom1 varchar(50);
 declare admin1 enum('0','1') ;

 declare cadena varchar(100);    /*string to concatenate table creation and insertion*/


 /*cursor declaration*/

 declare cursor1 cursor for select * from users.usuaris where admin = '1' ;
 declare continue handler for not found set @centinela = 1 ;


  /*create the table with the name that's passed as parameter*/

  set @cadena=concat("create table ",nombre,                 
               "(
                 id2 int not null primary key,
                 nom2 varchar(50),
                 admin2 enum ('0','1')
                 )" );

   prepare stmt from @cadena ;
   execute stmt ;
   deallocate prepare stmt;


/* loop that fetches the data from the table usuaris and 
 inserts them into the newly created table. */

  set @centinela = 0 ;
  open cursor1 ;

  bucle: loop
     fetch cursor1 into id1,nom1,admin1 ;

   if ( centinela = 1 ) then
    leave bucle ;
       end if ;

       /*logic condition to avoid entry duplication */

       if not exists (select * from users.usuaris where admin='1' and id=@id1) then
         set @cadena=concat("insert into ",nombre," values( ",id1,",'",nom1,"','",admin1,"')");
       end if;

      select @cadena;
      prepare stmt from @cadena;
      execute stmt ;
      deallocate prepare stmt;

  end loop bucle;
  close cursor1;

END

以下是用户的单表数据库:

 create database if not exists `users` ;

 use  `users` ;

 create table usuaris(

  id int not null auto_increment primary key ,
  nom varchar(50),
  admin enum ('0','1')

  );


  insert into  usuaris(id,nom,admin)
  values 
       (1,'jose','1'),
       (2,'maria','0'),
       (3,'frank','1'),
       (4,'mary','1'),
       (5,'godfrey','0') ;

2 个答案:

答案 0 :(得分:0)

还必须复制jose。重复的原因 - 如果IF语句不是TRUE,那么您不必设置新的@cadena变量,但仍然执行PREVIOUS @cadena语句。您还应该将执行转移到IF语句中:

   if not exists (select * from users.usuaris where admin='1' and id=@id1) then
     set @cadena=concat("insert into ",nombre," values( ",id1,",'",nom1,"','",admin1,"')");
     select @cadena;
     prepare stmt from @cadena;
     execute stmt ;
     deallocate prepare stmt;
    end if;

同样在SQL中,如果可能的话,应该尽量避免使用循环,而是使用SQL语句。 您可以使用一个SQL语句替换循环:

INSERET INTO NEW_TABLE_NAME_HERE 
        SELECT id1,nom1,admin1 
        FROM users.usuaris where admin<>'1'

您还可以使用SELECT INTO语句语法自动创建没有CREATE TABLE语句的新表:

    SELECT id1 as id2,
           nom1 as nom2,
           admin1 as admin2 
    INTO NEW_TABLE_NAME_HERE
    FROM users.usuaris where admin<>'1'

答案 1 :(得分:0)

将以下代码更改为我的新代码并尝试 -

现有代码

if not exists (select * from users.usuaris where admin='1' and id=@id1) then
         set @cadena=concat("insert into ",nombre," values( ",id1,",'",nom1,"','",admin1,"')");
       end if;

      select @cadena;
      prepare stmt from @cadena;
      execute stmt ;
      deallocate prepare stmt;

新守则 -

SET @cnt=SELECT count(*) FROM users.usuaris WHERE admin='1' AND id=@id1
    IF @cnt>0 THEN
         SET @cadena=CONCAT("insert into ",nombre," values( ",id1,",'",nom1,"','",admin1,"')");
      prepare stmt from @cadena;
      execute stmt ;
      deallocate prepare stmt;
       end if;