none
Tabella SQL e campo Identity RRS feed

  • Domanda

  • Salve a tutti,

    ho una domanda su come impostare un campo identity .  Attualmente ho un db access che vorremmo dismettere per passare ad un sql ed usare vb net per la gestione  .

    Volevo creare una tabella con campo identity come chiave, che mi andrà ad identificare il numero del contratto. Ad ogni anno però volevo azzerae questo numeratore.

    Ovviamente mi darà errore di indice duplicato, come dovrei progettare la tabella secondo voi ?

    grazie

    giovedì 17 settembre 2020 15:07

Tutte le risposte

  • Ciao,

    un campo identity lo puoi usare tenendolo come primary key della tabella; per quel che riguarda il numero contratto puoi usare semplicemente un campo smallint o int - a seconda del volume annuale dei contratti - valorizzandolo opportunamente.

    Per valorizzare in modo progressivo all'interno dell'anno puoi ricorrere ad un trigger di insert oppure creare un'apposita stored procedure che faccia la insert e contenga la logica di calcolo del num. contratto,  che sarà del tipo  1+isnull( max(numero contratto), 0 ) ... where Anno = @AnnoFissato.

    In entrambi i casi vi sarebbe una criticità qualora questa tabella avesse un tasso di insert - ovvero di creazione contratti - elevato e parallelo, ma mi pare di capire che non sia il vostro caso; viceversa andrebbe studiata una soluzione un poco più complessa.

    Giorgio

    venerdì 18 settembre 2020 03:56
  • Ciao,

    Il campo identity puoi usarlo come chiave primaria dell tabella, mentre per il numero del contratto userei una coppia di campi: [Numero] + [Anno], che puoi impostare come unique key.

    Potresti anche provare a mettere l'indice clustered sulla chiave [Numero] + [Anno] invece che sulla PK, ma dipende molto da come accedi ai dati di quella tabella. Ti consiglio di fare qualche prova "sul campo".

    Ti sconsiglio caldamente l'uso di trigger per gestire l'inserimento: il fatto che tu debba azzerare il contatore ad inizio anno è "Business Logic", e mettere business logic nel database può dare diversi problemi di manutenibilità dell'applicazione. 

    HTH


    Alberto Dallagiacoma [MCP, MCTS]

    My Italian Blog | Twitter | LinkedIn
    DotDotNet - User Group .NET Emilia Romagna

    venerdì 18 settembre 2020 07:27
  • grazie a tutti per le risposte.

    Purtroppo l'inserimento del contratto può essere parallelo.

    Faccio un pò di prove , il tempo per fortuna non manca per sviluppare questa cosa , fino a che regge l'atttuale db di access.

    grazie

    venerdì 18 settembre 2020 10:37
  • In tal caso, per quel che riguarda l'ipotesi tramite trigger, l'implementazione che propongo assomiglierebbe a qualcosa del genere:


    create table contr(id int identity primary key, anno int not null, numero int not null); go create unique index ux on dbo.contr(anno, numero); go create or alter trigger trg on contr after insert as begin if @@rowcount<>1 return; declare @anno int, @id int select @anno =anno, @id =id from inserted; update dbo.contr set numero= 1+isnull((select MAX(numero) from dbo.contr where anno=@anno), 0) where id=@id; end

    go

    -- esempio:

    insert into  dbo.contr(anno, numero) values(2020,0);

    I vantaggi sono:

    1. la gestione del contatore è di fatto embedded alla tabella, azzerando problemi di manutenzione, bachi, sincronizzazione di logiche applicative tra più sorgenti (Form, Web, App, etc)
    2. nessuna operazione da gestire manualmente per azzerare il contatore ad inizio anno
    3. nessuna transazione da implementare e ben governare lato applicativo/i, indispensabile per evitare conflitti di calcolo del nuovo numero da assegnare ed evitare buchi
    4. l'assegnazione progrerssiva e senza buchi è robusta anche in caso di rollback.

    Il fattore chiave di questa implementazione è giocato dall'indice univoco su anno+numero.

    Giorgio

    venerdì 18 settembre 2020 13:03
  • Quanto spesso viene inserito un contratto?

    Se non hai un rate di insert molto alto, non dovrebbe essere un problema gestire la numerazione progressiva lato applicativo.


    Alberto Dallagiacoma [MCP, MCTS]

    My Italian Blog | Twitter | LinkedIn
    DotDotNet - User Group .NET Emilia Romagna

    venerdì 18 settembre 2020 13:05
  • Ciao a tutti,

    in aggiunta alle soluzioni descritte da Giorgio e Alberto, il contatore Anno + Numero potrebbe essere implementato con un oggetto Sequence.

    Per il reset annuale, un esempio è disponibile qui.

    Ciao!


    Sergio Govoni

    Microsoft Data Platform MVP | MVP Profile | English Blog | Twitter | LinkedIn

    domenica 27 settembre 2020 09:50
    Moderatore