Impedire inserimento dati doppi nel db

di il
17 risposte

Impedire inserimento dati doppi nel db

Buongiorno a tutti

chiedo cortesemente suggerimenti per aggiustare un db realizzato anni fa nella P.A. dove lavoro, che necessita di upgrade frequanti..ormai il personale non è più attento a cosa fa perciò tocca “blindarli” nelle operazioni

il DB è molto semplice, una mera raccolta dati con report mensili. 

 tra i vari campi ho nome, nazione, IMO, data, ora, ecc ecc ; il campo IMO è un campo numerico obbligatorio (duplicati ammessi)

vorrei mettere un controllo affinchè durante l'inserimento dei dati non si possa inserire due volte nello stesso giorno lo stesso codice IMO, ma non saprei da che parte cominciare …

tra l'altro non so se avviare il controllo con un  “dopo aggiornamento” nel form del campo successivo (ora) oppure avviarlo quando si clicca sul bottone “inserisci dati” 

grazie per la vostra disponibilità

Valter

17 Risposte

  • Re: Impedire inserimento dati doppi nel db

    Per poterti aiutare velecemente e con sicurezza sarebbe importante avere il file a disposizione quindi dovresti postarlo se possibile con un minimo di dati altrimenti anche vuoto.

  • Re: Impedire inserimento dati doppi nel db

    valtere ha scritto:

    Ma il nick è un omaggio al “Vàltere” di Gigi Proietti?

    =======

    06/09/2024 - valtere ha scritto:

    necessita di upgrade frequanti..ormai il personale non è più attento a cosa fa perciò tocca “blindarli” nelle operazioni

    Ahia… mi sa che è stato studiato male fin dall'inizio. L'utente sbaglia, più o meno incosapevolmente, a volte riesce a sbagliare in modi che manco il più esperto aveva pensato potessero esistere, però è compito di chi prepara il tutto rendere la vita impossibile a chi vuole (o tende a) sbagliare.

    Che cosa intendi per “upgrade frequenti”? Forse è una cosa marginale ma non vorrei che sotto ci fosse qualcosa che mi/ci sfugge

    06/09/2024 - valtere ha scritto:

    mettere un controllo affinchè durante l'inserimento dei dati non si possa inserire due volte nello stesso giorno lo stesso codice IMO,

    IMO è creato automaticamente o digitato a mano dall'utente? Nella tabella deve essere presente la data di inserimento, ovviamente, altrimenti quel tipo di controllo non è fattibile.

    Evento BeforeUpdate della maschera, fai la ricerca per data e IMO, se la ricerca dà esito positivo imposti il Cancel di BeforeUpdate a 1 e l'aggiornamento non avviene (inteso anche come inserimento). Non so cosa contiene il pulsante Inserisci dati, forse puoi fare la stessa cosa lì. Ovviamente darai questa informazione all'utente, in modo che non continui imperterrito, magari premendo il pulsante a raffica.

    Per fare la ricerca c'è il più banale dei DLookup oppure potresti fare un FindFirst sulla proprietà RecordsetClone della maschera. In entrambi i casi devi impostare il criterio di ricerca con il valore di IMO che c'è nel controllo e con la data odierna. DLookup restituisce un null se non trova niente, con il FindFirst se non trova nulla la proprietà NoMatch assuma valore “Vero”.

    Te l'ho spiegata come concetto, non con il codice, prova e poi vediamo.

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - Philcattivocarattere ha scritto:


    Ma il nick è un omaggio al “Vàltere” di Gigi Proietti?

    il Gigi non c'entra nulla…quando hai a che fare con tanti colleghi romani succedono queste cose …

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - Philcattivocarattere ha scritto:


    IMO è creato automaticamente o digitato a mano dall'utente? Nella tabella deve essere presente la data di inserimento, ovviamente, altrimenti quel tipo di controllo non è fattibile.

    tutto nasce da lunga data, da autodidatta (e grande aiuto del sitocomune) anni 90 con le prime versioni di access; modifiche ed integrazioni per sopperire alle varie esigenze e/o facilitare il lavoro dei colleghi. 

    il DB è residente su cartella del NAS, classica maschera di apertura  con i vari campi, alcuni collegati ad altre tabelle per avere uniformità dei dati (es. le nazioni)…di norma viene usato da un operatore alla volta…!!

    i dati vengono inseriti digitando a mano tutte le informazioni (nome, nazione, imo ecc) data compresa (che non è quella del sistema/pc) poiche puo capitare di registrare i dati nel db anche il giorno dopo

    ho preparato una versione leggera del db, dovesse servire (sono 4 campi) ..compressa in 7z, ma non trovo il modo di caricarla

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - valtere ha scritto:

    compressa in 7z, ma non trovo il modo di caricarla

    Infatti non puoi, devi caricarla su un sistema di file sharing e pubblicare il link.

    06/09/2024 - valtere ha scritto:

    il DB è residente su cartella del NAS, classica maschera di apertura  con i vari campi, alcuni collegati ad altre tabelle per avere uniformità dei dati (es. le nazioni)…di norma viene usato da un operatore alla volta…!!

    Di norma? Spero che almeno ci sia un front end distribuito singolarmente ai vari operatori (da salvare in locale)

    Vuoi un altro sistema semplicissimo da applicare e che poi però devi gestire “come errore” nella maschera? Crea un indice multicampo per IMO e Data di inserimento, impostando a duplicati non ammessi. Effetti indesiderati di questo sistema: se non c'è una ricerca per data ed IMO questo indice non serve a niente se non a prevenire il doppio inserimento. Diventa cioè un indice “inutile”, che appesantisce il database, mentre puoi ottenere lo stesso risultato con il codice di cui sopra. Anche se con una ricerca per data ed IMO dovresti comunque indicizzare anche il campo data (se si vuole sfruttare al meglio la ricerca con “rushmore dello showplan"). Per un database piccolo non vedi alcuna differenza. Se invece è bello grande e il caricamento/inserimento è addirittura massivo la differenza si può notare ma dici che avviene tutto a mano quindi…

  • Re: Impedire inserimento dati doppi nel db

    Select campi interessati from tabella incriminata where data=data che stai inserendo and imo=imo che stai inserendo

    Esegui e se esiste un record allora stai duplicando…

    Banale!

    La p.a. con access? 

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - valtere ha scritto:


    vorrei mettere un controllo affinchè durante l'inserimento dei dati non si possa inserire due volte nello stesso giorno lo stesso codice IMO, ma non saprei da che parte cominciare …

    Ti consiglierei di mettere sul db un indice unico sui campi che vuoi mantenere unici

    Ad esempio   data_odierna + valore_imo  

    Poi lato codice, tenti l'inserimento del record e verifichi se da' errore oppure no

    Se da' errore allora lo decodifichi e se fosse il caso (imo duplicato nello stesso giorno) lo presenti all'operatore

    Cosi' ti risolvi il problema anche del tentativo inserimento stesso imo da postazioni differenti

  • Re: Impedire inserimento dati doppi nel db

    Come vedi ci sono n-mila modi…

    Il meno invasivo resta la sql.

    La carichi da file o da tabella e se domani devi controllare un terzo valore modifichi la sql senza toccare le strutture delle tabelle.

    Se decidi di toccare le tabelle accertati che la modifica non ti blocca altre form.

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - sihsandrea ha scritto:


    Select campi interessati from tabella incriminata where data=data che stai inserendo and imo=imo che stai inserendo

    Esegui e se esiste un record allora stai duplicando…

    Banale!

    La p.a. con access? 

    Diciamo che la sequenza controllare+scrivere  rischi che qualcun altro scriva prima di te

    Se metti dieci postazioni in loop ad inserire record, prima o poi lo trovi il doppione

    E' sicuramente poco frequente, ma puo' succedere

    Mettere l'indice unico nel db e' sicuro che non riesci a fregarlo, la riga non entra

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - amorosik ha scritto:


    Mettere l'indice unico nel db e' sicuro che non riesci a fregarlo, la riga non entra

    Mi associo totalmente: gli indici sono senz'altro il modo più efficace di evitare i duplicati.

    Per far funzionare il “gioco”, è sufficiente trovare l'espediente tale per cui i record che non devono essere inseriti abbiano lo stesso valore all'interno di un campo scelto, in modo che il tentativo di inserimento fallisca a causa del codice univoco.

    Tanto, in ogni caso, l'indice andrebbe messo comunque: se la condizione viene verificata tramite SQL, allora significa che si faranno query frequenti per il campo da verificare, e questo presuppone che il processo sia efficiente, da cui la necessità dell'indice.

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - Alka ha scritto:


    Mi associo totalmente: gli indici sono senz'altro il modo più efficace di evitare i duplicati.

    Diciamo che gli indici sono  piu 'efficaci MA ci sono alcune note da ricordare:

    1. creare l'indice vuol dire modificare il database, dove una semplice query e' SOLO questione di codice
    2. quando si fa una insert che viola un “constraint” viene generata un'"eccezzione" che deve essere opportunamente gestita, dove la query e' ESPLICITAMENTE implementata e quindi il problema e' anche ESPLICITAMENTE gestito
    3. la violazione del “constraint” non e' l'UNICO tipo di eccezzione che si potrebbe verificare, quindi quando si gestisce l'eccezzione si deve controllare se e' stata generata ESATTAMENTE dalla duplicazione de codice e NON per qualche altro motivo.
    4. il doppio statement non impatta significativamente sulle performance, SE e' fatto a fronte di un'azione “umana” i cui tempi sono nell'ordine del secondo o piu', la' dove una select impiega forse 1 millisecondo (quindi si possono gestire 500 select+insert al secondo)

    .

    Insomma, “si MA forse”

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - migliorabile ha scritto:


    creare l'indice vuol dire modificare il database, dove una semplice query e' SOLO questione di codice

    Se la query viene eseguita a ogni inserimento/aggiornamento, e quindi viene eseguita frequentemente, quei campi andrebbero indicizzati.

    06/09/2024 - migliorabile ha scritto:


    quando si fa una insert che viola un “constraint” viene generata un'"eccezzione" che deve essere opportunamente gestita, dove la query e' ESPLICITAMENTE implementata e quindi il problema e' anche ESPLICITAMENTE gestito

    Se l'eccezione è opportunamente gestita, quella “gestione opportuna” è anche una “gestione esplicita”.

    06/09/2024 - migliorabile ha scritto:


    la violazione del “constraint” non e' l'UNICO tipo di eccezzione che si potrebbe verificare, quindi quando si gestisce l'eccezzione si deve controllare se e' stata generata ESATTAMENTE dalla duplicazione de codice e NON per qualche altro motivo.

    Qualsiasi libreria di accesso ai dati ti fornisce tutte queste informazioni, e molte di più. Non vedo il problema.

    06/09/2024 - migliorabile ha scritto:


    il doppio statement non impatta significativamente sulle performance

    Essendo un “doppio” statement, i tempi sono esattamente il doppio, anche di più senza l'indice e in presenza di molti dati.

    06/09/2024 - migliorabile ha scritto:


    SE e' fatto a fronte di un'azione “umana” i cui tempi sono nell'ordine del secondo o piu', la' dove una select impiega forse 1 millisecondo (quindi si possono gestire 500 select+insert al secondo)

    L'azione umana può attendere di più, ma le tempistiche variano sensibilmente all'aumentare dei dati, a meno di non mettere un indice, da cui poi la scelta di far lavorare l'indice a questo scopo. La SELECT impiega forse 1 millisecondo, ma non sarà sempre così all'aumentare dei dati. Di fatto si sta già realizzando un sistema che non è scalabile.

    06/09/2024 - migliorabile ha scritto:


    Insomma, “si MA forse”

    Manca comunque la gestione delle problematiche indicate dall'utente amorosik: per evitare violazioni alla regola, devi mettere in gioco transazioni o “blocco di record”, e questo è senz'altro ben più complesso di gestire una eccezione per motivi specifici (e documentabili/commentabili, nel codice e altrove), posto che senza indice i tempi della query aumentano comunque all'aumentare dei dati.

    Il “forse” lo metterei solo in un caso: qualora la condizione da verificare fosse particolarmente complessa da non poter essere realizzata con un semplice indice univoco. Ma un indice andrebbe inserito comunque per la query sui campi coinvolti, pena il degrado al crescere del volume di dati.

    Poi certo, stiamo parlando di Access, quindi non mi aspetto uno scenario di Big Data… :D

  • Re: Impedire inserimento dati doppi nel db

    Beh, era un modo ulteriore per eseguire i controlli.

    Poi si può mettere in un trigger.

    Tuttava è più facile fare 6 al susperenalotto con 1 euro che inserire contemporaneamente il record. Uno dei due riceve il messaggio.

    Vado ot, i casi di un duplicato del dato possono essere (da una deduzione):

    Si tenta di inserire una pratica già inserita (dubito che le pratiche nascano con un codice duplicato, sarebbe un errore di duplicato a monte), come testimoniato che la data potrebbe essere antecedente alla data di inserimento.

    Si digita male la data o chi prima di lui ha digitato male la data.

    Si digita male il codice o qualcuno ha digitato male il codice.

    Si sta reinserendo una pratica già inserita.

    Hai inserito il record e dopo qualche minuto lo elimini o non lo salvi ma questo non deve portare alla possibilità di inserire duplicati. So da subito se ho inserito l'ordine 10 del cliente pippo, non aspetto di scrivere 40 righe per vedere il messaggio “ordine già esistente”.

    In tutti questi casi il dato risulta presente quindi lontano dalla corsa al click del post del record.

    Ma soprattutto, quel dato lo scelgo tirando i dadi o ha un senso? Ergo, c'è un errore a monte perché dovrebbe essere unico per quella data.

    Io userei dei barcode o qrcode a monte per dati così sensibili o necessari.

    Fine ot. La mia era una tra le varie alternative.

    Per i tempi di esecuzione, siamo nell'ordine di una frazione di secondo, credo che il controllo possa essere fatto nel momento in ciu si scrive il codice nel campo e, perche no, anche al post del record.

  • Re: Impedire inserimento dati doppi nel db

    06/09/2024 - valtere ha scritto:


    Buongiorno a tutti

    chiedo cortesemente suggerimenti per aggiustare un db realizzato anni fa nella P.A. dove lavoro, che necessita di upgrade frequanti..ormai il personale non è più attento a cosa fa perciò tocca “blindarli” nelle operazioni

    il DB è molto semplice, una mera raccolta dati con report mensili. 

     tra i vari campi ho nome, nazione, IMO, data, ora, ecc ecc ; il campo IMO è un campo numerico obbligatorio (duplicati ammessi)

    vorrei mettere un controllo affinchè durante l'inserimento dei dati non si possa inserire due volte nello stesso giorno lo stesso codice IMO, ma non saprei da che parte cominciare …

    tra l'altro non so se avviare il controllo con un  “dopo aggiornamento” nel form del campo successivo (ora) oppure avviarlo quando si clicca sul bottone “inserisci dati” 

    grazie per la vostra disponibilità

    Valter

    Hai 2 Opzioni come ti è già stato detto:

    1. CHIAVE PRIMARIA MULTICAMPO, ed intercetti l'errore di VIOLAZIONE PK, si fa su evento FORM_ERROR, ed intercetti errore 3022
    2. Sfrutti la transazione insita nativa in Access su evento Before_Insert, e quì verifichi con un DLOOKUP che il record con criterio dato dall'AND dei campi indicati non sia già presente, nel caso annulli la transazione fozando il CANCEL=TRUE 
Devi accedere o registrarti per scrivere nel forum
17 risposte