Postgresql Oledb column name quoting - postgresql

I have:
INSERT INTO XYZ (c1, c2, range) VALUES (?, ?, ?)
OleDb call fails here because of range is a reserved keyword - how to quote it through the OleDB?

Use double quotes ":
INSERT INTO XYZ (c1, c2, "range") VALUES (?, ?, ?)

Related

Spring Batch lower case table names

If you create the tables by Liquibase, is it possible to make the table names lower case? Or are there side effects and this is not a good recommendation?
# Done by Liquibase
spring.batch.jdbc.initialize-schema=never
I think it would be a bad idea since the upper case table names are hard coded in spring batch. For example the following is used in JdbcJobExecutionDao...
private static final String SAVE_JOB_EXECUTION = "INSERT into %PREFIX%JOB_EXECUTION(JOB_EXECUTION_ID, JOB_INSTANCE_ID, START_TIME, "
+ "END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, VERSION, CREATE_TIME, LAST_UPDATED) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String CHECK_JOB_EXECUTION_EXISTS = "SELECT COUNT(*) FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?";
private static final String GET_STATUS = "SELECT STATUS from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?";

Utf 8 issue when saving an entity

I use spring boot 2 with jpa, hibernate and postgres.
In my build.gradle, I have
tasks.withType(JavaCompile) {
options.compilerArgs = ["-Xlint:unchecked", "-Xlint:deprecation", "-parameters"]
options.encoding = "UTF-8"
}
I posted some class here https://pastebin.com/WgDqZkjf
I get problem with utf8
In debug I see
select
nextval ('ignar.hibernate_sequence')
Hibernate:
select
nextval ('ignar.samples_id_seq')
Hibernate:
insert
into
ignar.samplings
(available_for_test, build_date, color_id, dimension_id, machine_id, print, product_id, reception_date, remark, special_try, test_done, to_print, delay_before_doing_test, press, quantity_received, dtype, id, year)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'TraditionalSamplings', ?, ?)
Hibernate:
insert
into
ignar.samples
(created_at, updated_at, absorption_printed, aen_remarque, certificat_include, cube, durability_printed, fresh_density, fresh_weigth, gen_remarque, label, position, sample_letter, sampling_id, sampling_year, absorption, absorption_number, coloration, coloration_number, compression, compression_number, density, draw_down, draw_down_number, durability, durability_number, granulometry, granulometry_number, organic_material, organic_material_number, scaling, scaling_number, id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2018-05-21 15:38:21.214 WARN 2973 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 22021
2018-05-21 15:38:21.215 ERROR 2973 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: invalid byte sequence for encoding "UTF8": 0x00
2018-05-21 15:38:21.215 ERROR 2973 --- [io-8080-exec-10] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.DataException: could not execute statement]
probably your char is causing the issue... try to convert it to String in your java file

Storing timestamp in PostgreSQL gives an error: "cannot cast type bigint to timestamp without time zone"

I've created my table with the following code:
CREATE TABLE "STORES" (
"STOREGLOBALID" SERIAL NOT NULL ,
"STOREUPDATEDATETIME" TIMESTAMP NOT NULL,
"CHAINID" BIGINT ,
"CHAINNAME" VARCHAR(50) ,
"SUBCHAINID" SMALLINT ,
"SUBCHAINNAME" VARCHAR(50) ,
"STOREID" SMALLINT ,
"STORENAME" VARCHAR(50) ,
"STORETYPE" SMALLINT ,
"ADDRESS" VARCHAR(50) ,
"CITY" VARCHAR(50) ,
PRIMARY KEY ("STOREGLOBALID")
);
When I try to insert timestamp by using the following SQL for preparing statement:
INSERT INTO "STORES"
("STOREGLOBALID",
"STOREUPDATEDATETIME",
"CHAINID",
"CHAINNAME",
"SUBCHAINID",
"SUBCHAINNAME",
"STOREID",
"STORENAME",
"STORETYPE",
"ADDRESS",
"CITY")
VALUES (DEFAULT, cast(? as timestamp), ?, ?, ?, ?, ?, ?, ?, ?, ?)
And the following Java code:
ps = con.prepareStatement(sql);
ps.setLong(1, store.getChainId());
ps.setTimestamp(2, new Timestamp(1000000000)); //this value is only for test purposes, actual value gives the same error
I get the following error:
cannot cast type bigint to timestamp without time zone Position: 235
I understand that I need to provide a timestamp, but when I do it as following:
ps.setTimestamp(2, new Timestamp(1000000000), Calendar.getInstance(TimeZone.getTimeZone("UTC")));
I get the same error. What am I doing wrong? Thank you.
The first argument of your prepared statement is used in
cast(? as timestamp)
and the result is stored in STOREUPDATEDATETIME, of type TIMESTAMP. And you're passing a long (store.getChainId()) as argument. So you're trying to cast a long to a timestamp.
The second argument of your prepared statement is stored in CHAINID, of type BIGINT. And you're passing a Timestamp as argument (new Timestamp(1000000000)). So PostgreSQL tries to transform this timestamp into a bigint.
The SQL should be
INSERT INTO "STORES"
("STOREGLOBALID",
"STOREUPDATEDATETIME",
"CHAINID",
"CHAINNAME",
"SUBCHAINID",
"SUBCHAINNAME",
"STOREID",
"STORENAME",
"STORETYPE",
"ADDRESS",
"CITY")
VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
And the Java should be
ps.setTimestamp(1, new Timestamp(1000000000));
ps.setLong(2, store.getChainId());

Scala Play Anorm: Placeholder not replaced

I've just started using Anorm and have stumbled across a weird behavior. When I try to do the following:
val userTableName: String = "User"
SQL("INSERT INTO {userTableName} (email, forename, surname, refreshToken) VALUES ({email}, {forename}, {surname}, {refreshToken})")
.on("userTableName" -> userTableName,
"email"->email,
"forename"->forename,
"surname"->surname,
"refreshToken"->refreshToken).executeInsert()
I the following error:
play.api.Application$$anon$1: Execution exception[[JdbcSQLException: Syntax error in SQL statement "INSERT INTO ?[*] (EMAIL, FORENAME, SURNAME, REFRESHTOKEN) VALUES (?, ?, ?, ?) "; expected "identifier"; SQL statement:
INSERT INTO ? (email, forename, surname, refreshToken) VALUES (?, ?, ?, ?) [42001-175]]]
at play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.8.jar:2.3.8]
at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.8.jar:2.3.8]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [play_2.11-2.3.8.jar:2.3.8]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [play_2.11-2.3.8.jar:2.3.8]
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) [scala-library-2.11.1.jar:na]
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "INSERT INTO ?[*] (EMAIL, FORENAME, SURNAME, REFRESHTOKEN) VALUES (?, ?, ?, ?) "; expected "identifier"; SQL statement:
INSERT INTO ? (email, forename, surname, refreshToken) VALUES (?, ?, ?, ?) [42001-175]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:332) ~[h2-1.3.175.jar:1.3.175]
at org.h2.message.DbException.getSyntaxError(DbException.java:197) ~[h2-1.3.175.jar:1.3.175]
at org.h2.command.Parser.readIdentifierWithSchema(Parser.java:2926) ~[h2-1.3.175.jar:1.3.175]
at org.h2.command.Parser.readTableOrView(Parser.java:5049) ~[h2-1.3.175.jar:1.3.175]
at org.h2.command.Parser.parseInsert(Parser.java:995) ~[h2-1.3.175.jar:1.3.175]
If I hardcode the table name
SQL("INSERT INTO User (email, forename, surname, refreshToken) VALUES ({email}, {forename}, {surname}, {refreshToken})")
.on("email"->email,
"forename"->forename,
"surname"->surname,
"refreshToken"->refreshToken).executeInsert()
it works. I solved the problem, but it would be better not to hardcode the table name for refactoring reasons. Why can't I use the dynamic mapping functionality of Anorm in this case?
As said by m-z, the syntax {placeholder} is only for parameter (when followed by .on("placeholder", value)).
You can mix plain String interpolation with this syntax SQL(s"SELECT $table ... {id}").

How can I insert into PostgreSQL using Perl, DBI and placeholders?

I am trying to insert a row into a pSQL table, specifying both keys and values as placeholders:
my #keys = keys %db_entr;
my #vals = values %db_entr;
my #items = (#keys, #values);
my $dbh = DBI->connect("DBI:Pg:dbname=testdb;host=localhost", "username", 'password', {'RaiseError' => 1});
my $sth = $dbh->prepare("INSERT INTO grid ( ?, ?, ? ) values ( ?, ?, ? )");
my $rows = $sth->execute(#items);
print "$rows effected\n";
However, whatever I do, this gives me an error:
DBD::Pg::st execute failed: ERROR: syntax error at or near "$1"
LINE 1: INSERT INTO grid ( $1, $2, ...
^ at ./file.pl line 262, <STDIN> line 11.
Does anyone have an idea of what I might be doing wrong?
You cannot use placeholders for column names like this:
INSERT INTO grid (?, ?, ?) VALUES (?, ?, ?)
You must specify column names explicitly and can use placeholders for values only:
INSERT INTO grid (x, y, z) VALUES (?, ?, ?)
You can't use placeholders for column names in the prepare call. The best you can do is to either interpolate the variable names into the SQL string or use sprintf to do the equivalent.
This is an example, but you may need to do something different. Note that it modifies the #items array, and you need to call prepare again each time the contents of #items may have changed.
my $sth = $dbh->prepare(
sprintf "INSERT INTO grid ( %s, %s, %s ) values ( ?, ?, ? )",
splice #items, 0, 3
);
my $rows = $sth->execute(#items);
print "$rows affected\n";