[Db] stored procedure per creare stringa univoca: funziona

Marcello Vezzelli marcello a vezz.it
Gio 23 Ago 2007 13:49:47 CEST


Ciao a tutti,
sono riuscito a fare quello che volevo, ovvero creare una stored 
procedure che generi una stringa pseudocasuale come chiave primaria, 
controlli che non esista, ne faccia la insert e se fallisce la insert 
tenti nuovamente con un'altra chiave.
Per testare le parti di duplicazione ho forzato l'assegnamento della 
nuova chiave a una chiave già presente nella tabella, usando un valore RAND.

Qualsiasi commento,chiarimento o miglioria è benvenuto.

I punti "chiave":

    BEGIN
      DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN END;
      SELECT id INTO i_id FROM meeting WHERE chiave=@newchiave COLLATE 
'latin1_general_cs';
    END;

Questo blocco permette di gestire quel maledetto "ERROR 1329 (02000): No 
data - zero rows fetched, selected, or processed"
che non mi faceva proseguire (se la chiave non viene trovata la query si 
interrompeva lì).

      SET @inserterror=0;
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @inserterror=1;
        INSERT INTO meeting (chiave,email) VALUES (@newchiave,campo1);
      END;

Questo blocco invece permette di gestire la violazione di chiave 
primaria nel caso in cui si inserisca una stringa già presente.

Ecco il codice con qualche commento:

delimiter //
use ew
//
DROP PROCEDURE IF EXISTS GetKey
//
CREATE procedure GetKey(IN campo1 VARCHAR(150),OUT p_text 
VARCHAR(30),OUT i_id INT)
BEGIN
  creachiave: LOOP
    SET @i=0;
    SET @x=0;
    SET @newchiave = '';
    SET 
@alpha='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    REPEAT
      SET @i=@i+1;
      SET @x=FLOOR(RAND() * (CHAR_LENGTH(@alpha)));
      SET @newchiave=CONCAT(@newchiave,SUBSTRING(@alpha, a x,1));
    UNTIL @i>24
    END REPEAT;
    
    /* simulo la creazione di una chiave duplicata per far ritornare 
i_id>0 alla select */
    IF FLOOR(RAND() * 2) = 0 THEN
      SET @newchiave='TDONZylEaeNXhCShVRwYRDvf';
    END IF;
    
    /* controllo se la chiave esiste */
    SET i_id = 0;
    BEGIN
      DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' BEGIN END;
      SELECT id INTO i_id FROM meeting WHERE chiave=@newchiave COLLATE 
'latin1_general_cs';
    END;
    IF (i_id=0) THEN /* significa che la chiave non c'è */
      /* simulo la creazione di una chiave duplicata per far fallire la 
insert */
      IF FLOOR(RAND() * 2) = 0 THEN
        SET @newchiave='TDONZylEaeNXhCShVRwYRDvf';
      END IF;
      SET @inserterror=0;
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @inserterror=1;
        INSERT INTO meeting (chiave,email) VALUES (@newchiave,campo1);
      END;
      IF @inserterror=0 THEN
        SET i_id=LAST_INSERT_ID();
        LEAVE creachiave;
      END IF;
    END IF;
  END LOOP;
  SET p_text = @newchiave;
END
//
delimiter ;
SET @test='';
SET @cid=-1;
CALL GetKey('ciao', a test, a cid);
SELECT @test, a cid;

Ciao
Marcello



Maggiori informazioni sulla lista Db