«

»

Giu 09

Tabelle con campi ad incremento automatico nel DB2 for i

Per creare una tabella SQL con un campo ad incremento automatico, in MySQL si specifica AUTO_INCREMENT. Esempio:

create table MIATABLE (
Id_Key int(11) NOT NULL AUTO_INCREMENT,
Descrizione varchar(100) not null with default,
PRIMARY KEY ('Id_Key') )

Se devi farlo su un server IBMi (AS/400) che come database di default utilizza il DB2 for i bisogna utilizzare GENERATED ALWAYS AS IDENTITY al posto di AUTO_INCREMENT. Esempio:

create table MIATABLE (
Id_Key int NOT NULL GENERATED ALWAYS AS IDENTITY,
Descrizione varchar(100) not null with default,
PRIMARY KEY (Id_Key) )

In questo caso si otterrà un incremento automatico di 1 ad ogni INSERT.
Ad esempio, dopo l’esecuzione delle seguenti 3 istruzioni di INSERT

INSERT INTO MIATABLE VALUES(DEFAULT , 'Paolo') ;
INSERT INTO MIATABLE VALUES(DEFAULT , 'Eustachio') ;
INSERT INTO MIATABLE VALUES(DEFAULT , 'Gino') ;

si otterrà il seguente risultato:

IdKey Descrizione
1 Paolo
2 Eustachio
3 Gino

Da notare l’utilizzo della keyword DEFAULT all’interno dei valori dell’istruzione INSERT. E’ necessaria per far si che sia il DB a valorizzare il campo Id_Key.

Se volessi che l’auto-incremento avesse un passo di incremento diverso da 1, dovrei specificare anche start with NN, increment by NN nell’istruzione precedente. Esempio:

create table MIATABLE (
Id_Key int NOT NULL GENERATED ALWAYS AS IDENTITY (start with 10, increment by 10),
Descrizione varchar(100) not null with default,
PRIMARY KEY (Id_Key) )

In questo caso Id_Key verrebbe incrementato di 10 ad ogni INSERT partendo dal valore 10 al primo inserimento.

Per conoscere il valore di un campo IDENTITY dopo un INSERT bisogna utilizzare la funzione IDENTITY_VAL_LOCAL(). In pratica la funzione IDENTITY_VAL_LOCAL() è per il DB2 for i quello che la funzione LAST_INSERT_ID() è per MySQL o SCOPE_IDENTITY è per MS SQL Server.

Ad esempio, dopo la terza operazione INSERT indicata sopra, è sufficiente eseguire l’istruzione:

select IDENTITY_VAL_LOCAL() from sysibm/sysdummy1

per conoscere il valore del campo IDENTITY Id_Key.

Ovviamente è possibile utilizzare la stessa funzione anche all’interno di una Stored Procedure valorizzando una variabile con il valore del campo IDENTITY immediatamente dopo aver eseguito l’operazione INSERT. Ad esempio:

...
insert into MITAYABLE (Descrizione) values(i_name);
set My_Var = IDENTITY_VAL_LOCAL();
...

Esiste anche un’altra possibilità di gestire l’auto-incremento: definire la colonna della tabella come GENERATED BY DEFAULT AS IDENTITY. La differenza principale tra BY DEFAULT e ALWAYS è abbastanza intuibile: con ALWAYS è sempre il DB2 ad occuparsi della valorizzazione della colonna e NON permette di forzare il dato in nessun modo. Questo permette al DB2 di garantire l’univocità del valore.

Utilizzando BY DEFAULT il DB2 incrementa il dato solo se non specificato, altrimenti assume quello indicato dall’utente/applicazione. In questo caso il DB2 non garantisce l’univocità che quindi è a carico dell’applicazione.

BY DEFAULT è molto comodo nel caso in cui la tabella debba essere copiata in schemi/librerie diverse perchè permette di mantenere gli stessi valori della tabella originaria mentre se la colonna fosse definita ALWAYS non sarebbe possibile garantirlo.

ATTENZIONE: una considerazione molto importante da fare è che con BY DEFAULT, se l’applicazione forza un valore superiore al massimo già inserito, il DB2 non aggiorna il proprio contatore ma mantiene il precedente valore, quindi i successivi inserimenti di record con valore di default arriveranno a replicare il valore precedentemente forzato dall’applicazione. Se la colonna è anche PRIMARY KEY si otterrà un errore per chiave duplicata.

Per evitare questo tipo di problemi è necessario resettare il contatore della colonna GENERATED BY DEFAULT AS IDENTITY ogni volta che si forza un valore superiore al massimo con il seguente comando:

ALTER TABLE <tabella> ALTER COLUMN <nome-colonna> RESTART WITH <nuovo_valore>

dove <nuovo-valore> dev’esse il MAX(<nome-colonna>) + 1.

 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>