SELECT variabile in PostgreSQL

di il
23 risposte

SELECT variabile in PostgreSQL

Supponete che un visitatore desideri trovare tutte le notizie create da un autore rientranti in un preciso arco temporale. Per fare ciò avrei bisogno di un form con 3 tag input:
- nome dell'autore;
- data di inizio;
- data di fine.
Supponete ora che il visitatore voglia trovare tutti le notizie di un autore. In questo secondo caso il discorso è ancora più semplice perché avrei bisogno di un form con 1 solo tag.
Supponete infine di voler cercare tutte le notizie in un preciso arco temporale, indistintamente da coloro che le hanno create.
Se faceste due conti con un form di 3 soli tag si dovrebbero scrivere come minimo 3 query ma in realtà se analizzaste bene il problema si potrebbero ottenere, senza grosso sforzo, molte più casistiche.
Se poi il form invece di 3 tag ne avesse molti di più il problema si complicherebbe enormemente. Da qui nasce la mia esigenza di scrivere una query 'variabile', perdonate il mio linguaggio poco tecnico ma credo che il discorso si capisca.
Come posso scrivere in PostgreSQL una query di ricerca per questa tabella?

CREATE TABLE IF NOT EXISTS notizie (
    id BIGSERIAL NOT NULL,
    id_utente BIGINT NOT NULL,
    titolo VARCHAR(150) NOT NULL,
    descrizione TEXT NOT NULL,
    luogo VARCHAR(100) NOT NULL,
    data TIMESTAMP WITH TIME ZONE NOT NULL,
    stato VARCHAR(100) NOT NULL,
    dettagli TEXT NOT NULL,
    CONSTRAINT notizie_fka_utenti FOREIGN KEY (id_utente) REFERENCES utenti (id) ON DELETE CASCADE,
    CONSTRAINT notizie_uk UNIQUE (titolo, descrizione, luogo, data),
    CONSTRAINT notizie_pk PRIMARY KEY(id)
);
Mi basta solo un pezzo di codice che illustri l'approccio, poi io mi aggiusto a scrivere il resto.
In pratica vorrei scrivere una query in jdbcTemplate che funzioni sia quando l'utente ha deciso di fare una ricerca per titolo che per luogo, ecc...
Grazie anticipatamente

23 Risposte

  • Re: SELECT variabile in PostgreSQL

    Se vuoi una query omnicomprensiva senza nemmeno specificare una condizione, temo che l'unica soluzione sia
    select * from notizie;
    Se invece vuoi una scorciatoia per usare postgresql, puoi guardare il tutorial ufficiale ed esercitarti
    https://www.postgresqltutorial.com
    https://extendsclass.com/postgresql-online.htm
  • Re: SELECT variabile in PostgreSQL

    Non mi aiuti molto Weierstrass.
    Nelle pagine che mi mandi è tutto ben spiegato, nulla da dire, ma non so come iniziare e come testare le query prima di scrivere il metodo con jdbcTemplate.
    Se nel query tools scrivo (è un esempio, non è quello che voglio arrivare a scrivere):
    
    SELECT notizie.* FROM notizie, utenti
    WHERE utenti.nome = 'Proprietario' AND notizie.id_utente = utenti.id
    AND notizie.id <=7 ORDER BY notizie.data ASC;
    
    in jdbcTemplate devo sostituire 'Proprietario' e 7 con il punto interrogativo.
    1) Come faccio a dire al DBMS di non considerare il pezzo "WHERE utenti.nome = 'Proprietario' AND notizie.id_utente = utenti.id AND" se 'Proprietario' è nullo oppure è una stringa vuota ""?
    2) Altra cosa che cercavo di fare è sostituire 'Proprietario' e 7 con 2 variabili per poi valorizzarle a null in modo da testare l'efficienza del mio eventuale script ma non riesco neppure a valorizzare 2 variabili:
    
    DO $$
        DECLARE
            input_id BIGINT = 7;
            input_nome VARCHAR(100) = 'Proprietario';
        BEGIN
            SELECT notizie.* FROM notizie, utenti
            WHERE utenti.nome = input_nome AND notizie.id_utente = utenti.id
            AND notizie.id <=input_id ORDER BY notizie.data ASC;
        END
    $$;
    
    
    [2021-11-07 23:23:16] [42601] ERRORE: la query non ha una destinazione per i dati restituiti
    [2021-11-07 23:23:16] Suggerimento: Se vuoi scartare i risultati di una SELECT, utilizza PERFORM.
    [2021-11-07 23:23:16] Dove: funzione PL/pgSQL inline_code_block riga 6 a istruzione SQL
    
  • Re: SELECT variabile in PostgreSQL

    Mi pare che il problema sia JDBCTemplate (vedo che fa parte del framework Spring), perché altrimenti la soluzione mi sembra banale: ti controlli i parametri a monte, poi con una if ti fai due statement SQL diversi e il secondo lo fai senza WHERE...

    Forse è più adatta la sezione Java
  • Re: SELECT variabile in PostgreSQL

    No no Weierstrass! Non conviene farlo con jdbcTemplate perché escono un sacco di casistiche ed un codice molto incasinato e lungo (ho già sperimentato). Vorrei risolvere con PostgreSQL. Non vuoi proprio darmi una mano? Mi vuoi cacciare via nella sezione Java?
  • Re: SELECT variabile in PostgreSQL

    Guardando la documentazione che mi hai mandato credo che IS NOT NULL ed INTERSECT possano tornarmi utili. Ho provato a scrivere questo codice ma il query tools mi informa che di vari errori nella grammatica del codice.
    Puoi darmi una mano?
    
    DO $$
        DECLARE
            input_id BIGINT = 7;
            --input_titolo VARCHAR(150) = 'La farfalla Brephidium exilis';
            input_titolo VARCHAR(150) = 'a';
        BEGIN
            SELECT notizie.* FROM notizie
            IF (SELECT notizie.* FROM notizie WHERE notizie.id <= input_id) IS NOT NULL THEN
                INTERSECT
                SELECT notizie.* FROM notizie WHERE notizie.id <= input_id;
            END IF;
            IF (SELECT notizie.* FROM notizie WHERE LOWER(notizie.titolo) LIKE LOWER('%input_titolo%')) IS NOT NULL THEN
                INTERSECT
                SELECT notizie.* FROM notizie WHERE LOWER(notizie.titolo) LIKE LOWER('%input_titolo%');
            END IF;
            ORDER BY notizie.data ASC;
        END
    $$;
    
  • Re: SELECT variabile in PostgreSQL

    Ciao,
    io lo risolverei in questo modo:
    
    where 1=1
    
    AND ((input1 IS NULL) OR (la tua condizione riferita a input1 per la colonna1))
    AND ((input2 IS NULL) OR (la tua condizione riferita a input2 per la colonna2))
    AND .......
    
    
  • Re: SELECT variabile in PostgreSQL

    Geniale Toki, grazie mille!
    Direi che il tuo codice è stupendo però c'è un problema di sintassi che non riesco a risolvere.
    
    DO $$
        DECLARE
            input_id BIGINT = 7;
            --input_titolo VARCHAR(150) = 'La farfalla Brephidium exilis';
            input_titolo VARCHAR(150) = 'a';
        BEGIN
            SELECT notizie.* FROM notizie
            WHERE 1=1
              (
                  AND ((input_id IS NULL) OR (notizie.id <= input_id))
                  AND ((input_titolo IS NULL) OR (LOWER(notizie.titolo) LIKE LOWER('%input_titolo%'))
              )
            ORDER BY notizie.data ASC;
        END
    $$;
    
  • Re: SELECT variabile in PostgreSQL

    Di che problema si tratta?
  • Re: SELECT variabile in PostgreSQL

    Non riesco a capire, sembra che dopo il where ci sia un errore di sintassi. Ho anche provato a togliere le parentesi ma senza successo.
    [2021-11-08 13:44:52] [42601] ERRORE: errore di sintassi a o presso "("
    [2021-11-08 13:44:52] Posizione: 240
    Con buona probabilità, al momento non posso testarlo, input_titolo non viene sostituito con 'a'.
    '%input_titolo%'
    Sembra che esista una funzione concat() ma non è questo il problema:
    DO $$
        DECLARE
            input_id BIGINT = 7;
            --input_titolo VARCHAR(150) = 'La farfalla Brephidium exilis';
            input_titolo VARCHAR(150) = 'a';
        BEGIN
            SELECT eventi.* FROM eventi
            WHERE 1=1
            (
                AND ((input_id IS NULL) OR (eventi.id <= input_id))
                AND ((input_titolo IS NULL) OR (LOWER(eventi.titolo) LIKE LOWER(CONCAT('%',input_titolo,'%')))
            )
                ORDER BY eventi.data ASC;
        END
    $$;
  • Re: SELECT variabile in PostgreSQL

    
            SELECT notizie.* FROM notizie
            WHERE 1=1
                  AND ((input_id IS NULL) OR (notizie.id <= input_id))
                  AND ((input_titolo IS NULL) OR (LOWER(notizie.titolo) LIKE LOWER('%input_titolo%')))
            ORDER BY notizie.data ASC;
    
  • Re: SELECT variabile in PostgreSQL

    Mi fornisce sempre lo stesso errore, anche questo:
    SELECT notizie.* FROM notizie
    WHERE 1=1
     AND ((7 IS NULL) OR (notizie.id <= 7))
     AND (('a' IS NULL) OR (LOWER(notizie.titolo) LIKE LOWER(CONCAT('%','a','%')))
     ORDER BY notizie.data ASC;
    
    [42601] ERRORE: errore di sintassi a o presso "ORDER" Posizione: 161
    
  • Re: SELECT variabile in PostgreSQL

    Scusa ho capito, mancava una parentesi.
  • Re: SELECT variabile in PostgreSQL

    Al momento non sto usando jdbcTemplate ma solo il query tools e ho ancora un problemino:
    DO $$
        DECLARE
            input_id BIGINT = 7;
            --input_titolo VARCHAR(150) = 'La farfalla Brephidium exilis';
            input_titolo VARCHAR(150) = 'a';
        BEGIN
            SELECT notizie.* FROM notizie
            WHERE 1=1
              AND ((input_id IS NULL) OR (notizie.id <= input_id))
              AND ((input_titolo IS NULL) OR (LOWER(notizie.titolo) LIKE LOWER(CONCAT('%',input_titolo,'%'))))
            ORDER BY notizie.data ASC;
        END
    $$;
    [42601] ERRORE: la query non ha una destinazione per i dati restituiti Suggerimento: Se vuoi scartare i risultati di una SELECT, utilizza PERFORM. Dove: funzione PL/pgSQL inline_code_block riga 7 a istruzione SQL
    Il tuo codice è più che perfetto ma a me interessa testare la query prima di passare a jdbcTemplate. Il mio obiettivo è scrivere:
    input_id BIGINT = NULL;
    e verificare che la query esegua una ricerca solo sulla base di input_titolo.
    Quando tutta funziona passo a jdbcTemplate e sostituisco 'input_id' con '?'. In questo modo se 'input_id' è 'null' il metodo non affonda inesorabilmente.
  • Re: SELECT variabile in PostgreSQL

    Ma ha senso tutto ciò? Se vuoi fare una query jolly, non è meglio farla in Java direttamente con un if opportuno, visto che è una cosa applicativa, invece di nasconderla nel database che tanto poi il codice è complicato uguale e in più hai nascosto tutto? Boh
Devi accedere o registrarti per scrivere nel forum
23 risposte