2013-02-05 14 views
13

Per esempio, ecco una tabella prodotto in PostgreSQL con status di enum:Come si inserisce un valore enum Postgres utilizzando Clojure JDBC?

create type product_status as enum ('InStock', 'OutOfStock'); 

create table product (
    pid   int primary key default nextval('product_pid_seq'), 
    sku   text not null unique, 
    name   text not null, 
    description text not null, 
    quantity  int not null, 
    cost   numeric(10,2) not null, 
    price   numeric(10,2) not null, 
    weight   numeric(10,2), 
    status   product_status not null 
); 

tipico codice Clojure per inserire un prodotto sarebbe:

(def prod-12345 {:sku "12345" 
       :name "My Product" 
       :description "yada yada yada" 
       :quantity 100 
       :cost 42.00 
       :price 59.00 
       :weight 0.3 
       :status "InStock"}) 

(sql/with-connection db-spec 
    (sql/insert-record :product prod-12345)) 

Tuttavia, status è un enum in modo da non può inserire come una stringa normale senza il cast di un enum:

'InStock'::product_status 

so che si può fare con uno stato preparato come:

INSERT INTO product (name, status) VALUES (?, ?::product_status) 

Ma c'è un modo per farlo senza utilizzare una dichiarazione preparata?

risposta

0

A meno che non si passi semplicemente SQL al back-end, sarà necessario utilizzare un cast. (L'istruzione SQL INSERT INTO product (name, status) VALUES ('SomeName', 'InStock'); dovrebbe funzionare correttamente)

Tom Lane addressed this issue su pgsql-hacker una settimana dopo aver fatto la domanda.

per quanto ne so questo è solo business come al solito con JDBC: setString() implica che il parametro è di un tipo stringa. Cadrà se il tipo effettivamente richiesto è il numero ma una stringa. (Non sono un esperto di Java, ma mi sembra di ricordare che utilizzando setObject invece è la soluzione standard.)

Enums non soffrono alcuna difficoltà speciale qui, e sarei contro indebolendo il sistema tipo per dare loro un pass speciale.

Il nostro @CraigRinger participated in that discussion, e potrebbe aver trovato qualcosa di rilevante ormai.

+2

Penso che @espeed stia chiedendo l'uso della libreria Clojure 'clojure.java.jdbc', non di Java JDBC. –

1

Kris Jurka replied alla discussione Mike Sherrill citata con una soluzione:

utilizzare il parametro url stringtype = non specificato [nell'URL della connessione JDBC] per avere setString legarsi sempre sconosciuto, invece di varchar, che quindi non dovrebbe richiedere modifiche al codice.

Ho provato questo in Java, e sembra funzionare bene.

2

Oggi ho funzionato usando la soluzione mod. .

È possibile aggiungere questo parametro alla db-spec come segue:

(def db-spec {:classname "org.postgresql.Driver" 
       :subprotocol "postgresql" 
       :subname "//myserver:5432/mydatabase" 
       :user "myuser" 
       :password "mypassword" 
       :stringtype "unspecified"}) ; HACK to support enums 

poi basta usare insert! come al solito.

Sarebbe bene avere una soluzione che non indebolisca così tanto la sicurezza del tipo.

+0

Mi sono imbattuto in [this] (https: //gist.github.com/rkneufeld/e5d1acbb007f47655508) in alternativa. un po 'più prolisso ma potrebbe valere la pena di essere esaminato. – jsonmurphy

Problemi correlati