2014-04-11 39 views
1

我有以下存储过程。我试图从表格中使用管理变量等于1的用户插入到存储过程使用作为参数传递的名称(nombre varchar(50))创建的表中。避免存储过程中出现重复条目​​的逻辑条件

当程序被调用时,它会复制用户'玛丽'与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 [email protected]) 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') ; 

回答

0

此外,它必须复制jose。重复的原因 - 如果IF声明不是TRUE,那么您不会设置新的@cadena变量,但无论如何执行PREVIOUS @cadena声明。你应该将执行到IF语句也:

if not exists (select * from users.usuaris where admin='1' and [email protected]) 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' 
0

改变乌尔到我的新代码和试戴

现有代码

if not exists (select * from users.usuaris where admin='1' and [email protected]) 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 [email protected] 
    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;