如何使用Clojure JDBC插入Postgres枚举值?

esp*_*eed 14 sql jdbc clojure

例如,这是PostgreSQL中的产品表,其状态为枚举:

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
);
Run Code Online (Sandbox Code Playgroud)

插入产品的典型Clojure代码是:

(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))
Run Code Online (Sandbox Code Playgroud)

但是,它status是一个枚举,因此您不能将其作为普通字符串插入而不将其强制转换为枚举:

'InStock'::product_status
Run Code Online (Sandbox Code Playgroud)

我知道你可以用准备好的声明来做,例如:

INSERT INTO product (name, status) VALUES (?, ?::product_status)
Run Code Online (Sandbox Code Playgroud)

但有没有办法在不使用准备好的声明的情况下做到这一点?

Mik*_*ll' 0

除非您将纯 SQL 传递到后端,否则您必须使用强制转换。(SQL 语句INSERT INTO product (name, status) VALUES ('SomeName', 'InStock');应该可以正常工作。)

在您提出问题一周后,Tom Lane 在 pgsql-hackers 上解决了这个问题。

AFAIK 这与 JDBC 一样:setString() 意味着参数是字符串类型。如果实际需要的类型不是字符串,它就会崩溃。(我不是 Java 专家,但我似乎记得使用 setObject 是标准的解决方法。)

枚举在这里并没有遭受任何特殊的困难,我反对削弱类型系统来给它们特殊的通行证。

我们自己的@CraigRinger参与了该讨论,并且现在可能已经找到了相关的内容。

  • 我认为 @espeed 是在询问 Clojure 库 `clojure.java.jdbc` 的使用,而不是 Java 的 JDBC。 (2认同)