Inserire un record con jdbcTemplate in una tabella con campi che possono essere riempiti oppure no

di iBaffiPro il
11 risposte
Ho la seguente tabella e non riesco a capire come gestire i campi 'componente_XX' che possono essere riempiti da numeri oppure possono restare vuoti. Se creo il classico metodo con 18 punti interrogativi ovviamente non funziona.

CREATE TABLE IF NOT EXISTS componenti (
    id_macchina BIGINT NOT NULL,
    id_elemento BIGINT NOT NULL,
    codice BIGINT NOT NULL,
    componente_1 BIGINT,
    componente_2 BIGINT,
    componente_3 BIGINT,
    componente_4 BIGINT,
    componente_5 BIGINT,
    componente_6 BIGINT,
    componente_7 BIGINT,
    componente_8 BIGINT,
    componente_9 BIGINT,
    componente_10 BIGINT,
    componente_11 BIGINT,
    componente_12 BIGINT,
    componente_13 BIGINT,
    componente_14 BIGINT,
    componente_15 BIGINT,
    CONSTRAINT componenti_fkb_macchine FOREIGN KEY (id_macchina) REFERENCES macchine (id) ON DELETE CASCADE,
    CONSTRAINT componenti_fka_elementi FOREIGN KEY (id_elemento) REFERENCES elementi (id) ON DELETE CASCADE,
    CONSTRAINT componenti_uk UNIQUE (id_macchina, codice),
    CONSTRAINT componenti_pk PRIMARY KEY(id_macchina, id_elemento)
);

11 Risposte

  • iBaffiPro ha scritto:


    che possono essere riempiti da numeri oppure possono restare vuoti.
    Cosa intendi per "vuoti"? NULL immagino .... non ci sono altre possibilità essendo dei BIGINT nullable.

    iBaffiPro ha scritto:


    Se creo il classico metodo con 18 punti interrogativi ovviamente non funziona.
    In che senso "non funziona"?? Non capisco il dubbio o la difficoltà.

    Un BIGINT nullable (su PostgreSQL, giusto?) equivale in Java a un java.lang.Long. Quindi o passi un oggetto Long o null.
  • Si tutto giusto. Ho capito dove sbagliavo. Scrivevo:
    ps.setLong(3, componenti.getComponente_1());
    invece di questo:
    ps.setLong(3, componenti.getComponente_1());
    grazie mille, pensavo che bisognasse fare altro
  • Ti faccio ancora una domanda. Per caso sai se è possibile modificare il mio schema aggiungendo questa condizione?
    codice, componente_1, componente_2, ..., componente_15 deveno essere tutti numeri diversi tra di loro;
    Spiegato in modo semplice, questo si:
    (9,2,3,4)
    questi no:
    (1,2,1,4) > ci sono 2 volte '1' nella stessa riga
    (17,9,6,6) > ci sono 2 volte '6' nella stessa riga
  • iBaffiPro ha scritto:


    Scrivevo:
    ps.setLong(3, componenti.getComponente_1());
    invece di questo:
    ps.setLong(3, componenti.getComponente_1());
    Ma ... non vedo differenze tra i due!

    Comunque, , se setti i dati con PreparedStatement (è una delle opzioni con JdbcTemplate) e vuoi passare un null, DEVI usare il setNull.
    Non setLong.
  • iBaffiPro ha scritto:


    Ti faccio ancora una domanda. Per caso sai se è possibile modificare il mio schema aggiungendo questa condizione?
    codice, componente_1, componente_2, ..., componente_15 deveno essere tutti numeri diversi tra di loro;
    Devi aggiungere un CONSTRAINT di check sulla tabella.
  • Ops, scusami, volevo scrivere:
    ps.setLong(3, componenti.getComponente_1());
    ps.setObject(3, componenti.getComponente_1());
  • iBaffiPro ha scritto:


    ps.setObject(3, componenti.getComponente_1());
    Sì, il setObject è ok ed evita la dualità setLong/setNull.
  • andbin ha scritto:


    iBaffiPro ha scritto:


    Ti faccio ancora una domanda. Per caso sai se è possibile modificare il mio schema aggiungendo questa condizione?
    codice, componente_1, componente_2, ..., componente_15 deveno essere tutti numeri diversi tra di loro;
    Devi aggiungere un CONSTRAINT di check sulla tabella.
    Però poi non trovo una funzione che verifichi la presenza di duplicati a parte i valori nulli ovviamente che sono duplicati accettabili.
  • iBaffiPro ha scritto:


    Però poi non trovo una funzione che verifichi la presenza di duplicati a parte i valori nulli ovviamente che sono duplicati accettabili.
    Se fossero poche colonne sarebbe facile, es. 3:
    CHECK c1 != c2 and c1 != c3 and c2 != c3

    Ma ... ne hai 15. Una possibilità è fare i check di ciascuna colonna verificando che sia diversa dalle altre.
    [CODE]CHECK c1 NOT IN (c2, c3, ......, c15), CHECK c2 NOT IN (c3, c4, ......, c15), CHECK c3 NOT IN (c4, c5, ......, c15), .... CHECK c13 NOT IN (c14, c15), CHECK c14 NOT IN (c15) -- o c14 != c15 c1, c2 ecc... i nomi reali delle colonne

    Probabilmente (sicuramente..) si può fare di meglio ma non ho altre idee ora ...
  • No, così è troppo complicato.
  • iBaffiPro ha scritto:


    No, così è troppo complicato.
    Puoi provare a "giocare" con gli array e la funzione UNNEST (che da un array di n elementi produce n righe).

    UNNEST(ARRAY[c1,c2,......,c15])

    Questo ti dà 15 righe, fai una select con GROUP BY verificando con un HAVING che un gruppo abbia più di 1 riga. Se esiste, vuol dire che c'è un duplicato.

    Alla fine il check verrebbe (ipotesi, non posso verificarlo)

    CHECK (EXISTS (SELECT ...... ))

    Ma prima prova "a mano" da un client a fare delle select usando anche valori numerici fissi. Conta vedere/verificare il concetto. Il check viene poi dopo.
Devi accedere o registrarti per scrivere nel forum
11 risposte