hello all, I have a sequence in postgresql, is there any way to use this sequence with next/jdbc to do insert! without using insert as string?
yes, that´s I want, like nextval
thank you
Hello Sean, your example is not working
this is working
(->
(sfmt-help/insert-into :smtb_flow)
(sfmt-help/values [{:id_flow (sfmt/call :nextval "seq_fluxo") :nm_flow "Teste" :id_company 1 :ds_flow_title "Teste" :dt_created (sfmt/call :NOW)}])
(sfmt/format {:parameterizer :none})
@fabrao are you using v2 as indicated? it worked for me:
(require '[honey.sql :as sql])
(require '[honey.sql.helpers :refer :all :as h])
(-> (insert-into :my_tbl)
(values [{:id [:nextval "my_seq"] :my_col "foo"}])
(sql/format {:inline true}))
produces
["INSERT INTO my_tbl (id, my_col) VALUES (NEXTVAL('my_seq'), 'foo')"]
when using
seancorfield/honeysql {:mvn/version "2.0.0-alpha2"}
Ho, I did not check about version 2
It's worth noting that the nextval('seq')
form works like that only because it is evaluated inline, but if you are not inlining all your parameters (and you probably should not do that -- b/c of SQL injection dangers), then you can just choose to line part of the expression:
(values [{:id [:nextval [:inline "my_seq"]] :my_col "foo"}])
(without the {:inline true}
in the sql/format
call)What will happen here is that "foo"
will be lifted out as a parameter, but the sequence name will be inlined:
["INSERT INTO my_tbl (id, my_col) VALUES (NEXTVAL('my_seq'), ?)" "foo"]
which gives you the best of both worlds.definitely worth noting, thanks! i was not aware that was possible
V2 syntax is a lot more composable than V1.
Can you explain what you mean by "a sequence in postgresql"?
Are you talking about arrays? There's a section in the docs about that: https://cljdoc.org/d/seancorfield/next.jdbc/1.1.613/doc/getting-started/tips-tricks#working-with-arrays
And, in general, if you don't want to work with strings -- and the next.jdbc.sql
functions don't do what you need -- the recommendation is always to use HoneySQL to produce the vector of SQL string and parameters.
(jdbc/execute! ds ["create sequence my_seq start 1 increment 2"])
=> [#:next.jdbc{:update-count 0}]
(jdbc/execute! ds ["create table my_tbl (id int primary key, my_col varchar)"])
=> [#:next.jdbc{:update-count 0}]
(jdbc/execute! ds ["insert into my_tbl values (nextval('my_seq'), ?)" "foo"])
=> [#:next.jdbc{:update-count 1}]
(jdbc/execute! ds ["select * from my_tbl"])
=> [#:my_tbl{:id 1, :my_col "foo"}]
(jdbc/execute! ds ["insert into my_tbl values (nextval('my_seq'), ?)" "bar"])
=> [#:next.jdbc{:update-count 1}]
(jdbc/execute! ds ["select * from my_tbl"])
=> [#:my_tbl{:id 1, :my_col "foo"} #:my_tbl{:id 3, :my_col "bar"}]
not sure if i hit on the nuance you are looking for?oh, not even close, you wanted to use insert!
one sec
it appears that insert!
expects all the values to be sent as ?-params, which is not how using seqs in postgres works afaik. so i dont think you'll be able to do this. however a suitably designed table doesnt need to explicitly use a sequence:
(jdbc/execute! ds ["create table my_serial_tbl (id serial primary key, my_col varchar)"])
=> [#:next.jdbc{:update-count 0}]
(require '[next.jdbc.sql :as sql])
=> nil
(sql/insert! ds :my_serial_tbl {:my_col "foo"})
=> #:my_serial_tbl{:id 1, :my_col "foo"}
(jdbc/execute! ds ["select * from my_serial_tbl"])
=> [#:my_serial_tbl{:id 1, :my_col "foo"}]
(def my-insert (-> (insert-into :my_tbl)
(values [{:id "nextval('my_seq')" :my_col "'foo'"}])
(sql/format :parameterizer :none)))
=> #'user/my-insert
(jdbc/execute! ds my-insert)
=> [#:next.jdbc{:update-count 1}]
(jdbc/execute! ds ["select * from my_tbl"])
=> [#:my_tbl{:id 1, :my_col "foo"} #:my_tbl{:id 3, :my_col "bar"} #:my_tbl{:id 5, :my_col "foo"}]
this is using honeysql as @seancorfield recommended. note that you have to supply the single quotes for strings when you turn off parameterization (which you have to do to get the nextval call to work)@chetlind_clojure That's with V1. Not much of that applies with V2 which handles string inlining correctly, as well as also supporting nextval
out of the box.
(-> (insert-into :my_tbl)
(values [{:id [:nextval "my_seq"] :my_col "foo"}])
(sql/format {:inline true}))
That should work on V2 as you expect.