How to set decimal value in java prepared statement.
I was tried as follows
My table query
create table A (x decimal(22,0))
In java I tried to set it as
preperedStatmentObj.setLong(1,aLongValue);
But i am getting the following error
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
Thank you
Try using setBigDecimal
BigDecimal d = new BigDecimal(aLongValue);
preperedStatmentObj.setBigDecimal(1, d);
Related
I have a postgres database to which I read/write using JOOQ. One of my DB tables has a column of type JSON. When I try to insert data into this column using the query below, I get the error
Exception in thread "main" org.jooq.exception.DataAccessException: SQL [update "public"."asset_state" set "sites_as_json" = ?]; ERROR: column "sites_as_json" is of type json but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Below is the code for inserting data into the column
SiteObj s1 = new SiteObj();
s1.setId("1");
s1.setName("Site1");
s1.setGeofenceType("Customer Site");
SiteObj s2 = new SiteObj();
s2.setId("2");
s2.setName("Site2");
s2.setGeofenceType("Customer Site");
List<SiteObj> sitesList = Arrays.asList(s1, s2);
int result = this.dsl.update(as).set(as.SITES_AS_JSON, LambdaUtil.convertJsonToStr(sitesList)).execute();
The call LambdaUtil.convertJsonToStr(sitesList) outputs a string that looks like this...
[{"id":"1","name":"Site1","geofenceType":"Customer Site"},{"id":"2","name":"Site2","geofenceType":"Customer Site"}]
What do I need to do to be able to insert into the JSON column?
Current jOOQ versions
jOOQ natively supports JSON and JSONB data types. You shouldn't need to have to do anything custom.
Historic answer
For jOOQ to correctly bind your JSON string to the JDBC driver, you will need to implement a data type binding as documented here:
https://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings
The important bit is the fact that your generated SQL needs to produce an explicit type cast, for example:
#Override
public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
// Depending on how you generate your SQL, you may need to explicitly distinguish
// between jOOQ generating bind variables or inlined literals.
if (ctx.render().paramType() == ParamType.INLINED)
ctx.render().visit(DSL.inline(ctx.convert(converter()).value())).sql("::json");
else
ctx.render().sql("?::json");
}
I am currently using h2 version 1.4.196. I have a CSV file as follows,
Status,message,code
1,hello,13
2,world,14
3,ciao,26
Following query works as expected & returns proper Status values.
select "Status" from CSVREAD('myfile.csv',
'Status,message,code', null) ;
Following query produces an exception. It seems like the literal string "Status" is being passed to convert instead of the values returned by the
execution of the query. I am not sure if my understanding of convert is
correct. Please help me with fixing this query to return the desired result. Thanks in advance.
select convert("Status", int) from CSVREAD('myfile.csv', 'Status,message,code', null) ;
Caused by: java.lang.NumberFormatException: For input string: "Status"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at org.h2.value.Value.convertTo(Value.java:940)
----------------------Detailed Exception------------------------------
select convert("Status", int) from CSVREAD('myfile.csv',
'Status,message,code', null) ;
Data conversion error converting "Status"; SQL statement:
select convert("Status", int) from CSVREAD('myfile.csv',
'Status,message,code', null) [22018-196] 22018/22018 (Help)
org.h2.jdbc.JdbcSQLException: Data conversion error converting "Status"; SQL statement:
select convert("Status", int) from CSVREAD('myfile.csv',
'Status,message,code', null) [22018-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:168)
at org.h2.value.Value.convertTo(Value.java:996)
at org.h2.expression.Function.getSimpleValue(Function.java:945)
at org.h2.expression.Function.getValueWithArgs(Function.java:1196)
at org.h2.expression.Function.getValue(Function.java:591)
at org.h2.command.dml.Select$LazyResultQueryFlat.fetchNextRow(Select.java:1459)
at org.h2.result.LazyResult.hasNext(LazyResult.java:79)
at org.h2.result.LazyResult.next(LazyResult.java:59)
at org.h2.command.dml.Select.queryFlat(Select.java:519)
at org.h2.command.dml.Select.queryWithoutCache(Select.java:625)
at org.h2.command.dml.Query.queryWithoutCacheLazyCheck(Query.java:114)
at org.h2.command.dml.Query.query(Query.java:371)
at org.h2.command.dml.Query.query(Query.java:333)
at org.h2.command.CommandContainer.query(CommandContainer.java:113)
at org.h2.command.Command.executeQuery(Command.java:201)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:186)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:164)
at org.h2.server.web.WebApp.getResult(WebApp.java:1380)
at org.h2.server.web.WebApp.query(WebApp.java:1053)
at org.h2.server.web.WebApp$1.next(WebApp.java:1015)
at org.h2.server.web.WebApp$1.next(WebApp.java:1002)
at org.h2.server.web.WebThread.process(WebThread.java:164)
at org.h2.server.web.WebThread.run(WebThread.java:89)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NumberFormatException: For input string: "Status"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at org.h2.value.Value.convertTo(Value.java:940)
... 22 more
The way you're using it you're defining the columns and reading all the rows from the csv, so you're getting the first row with Status as well. Then you try to convert the string Status to an integer which obviously results in exeption.
Instead you shouldn't define the columns but let h2 get them from the first row of the csv:
select convert(status,int) from CSVREAD('myfile.csv');
In a PostgreSQL 9.5 table I have an integer column social.
When I try to update it in a stored procedure given the following JSON data (an array with 2 objects, each having a "social" key) in the in_users variable of type jsonb:
'[{"sid":"12345284239407942","auth":"ddddc1808197a1161bc22dc307accccc",**"social":3**,"given":"Alexander1","family":"Farber","photo":"https:\/\/graph.facebook.com\/1015428423940942\/picture?type=large","place":"Bochum,
Germany","female":0,"stamp":1450102770},
{"sid":"54321284239407942","auth":"ddddc1808197a1161bc22dc307abbbbb",**"social":4**,"given":"Alxander2","family":"Farber","photo":null,"place":"Bochum,
Germany","female":0,"stamp":1450102800}]'::jsonb
Then the following code is failing:
FOR t IN SELECT * FROM JSONB_ARRAY_ELEMENTS(in_users)
LOOP
UPDATE words_social SET
social = t->'social',
WHERE sid = t->>'sid';
END LOOP;
with the error message:
ERROR: column "social" is of type integer but expression is of type jsonb
LINE 3: social = t->'social',
^
HINT: You will need to rewrite or cast the expression.
I have tried changing that line to:
social = t->'social'::int,
but then I get the error:
ERROR: invalid input syntax for integer: "social"
LINE 3: social = t->'social'::int,
^
Why doesn't PostgreSQL recognize that the data is integer?
From the JSON-TYPE-MAPPING-TABLE I was having the impression that JSON number would be auto-converted to PostgreSQL numeric type.
A single set-based SQL command is far more efficient than looping:
UPDATE words_social w
SET social = (iu->>'social')::int
FROM JSONB_ARRAY_ELEMENTS(in_users) iu -- in_user = function variable
WHERE w.sid = iu->>'sid'; -- type of sid?
To answer your original question:
Why doesn't PostgreSQL recognize that the data is integer?
Because you were trying to convert the jsonb value to integer. In your solution you already found that you need the ->> operator instead of -> to extract text, which can be cast to integer.
Your second attempt added a second error:
t->'social'::int
In addition to the above: operator precedence. The cast operator :: binds stronger than the json operator ->. Like you found yourself already, you really want:
(t->>'social')::int
Very similar case on dba.SE:
Querying JSONB in PostgreSQL
I've ended up using:
FOR t IN SELECT * FROM JSONB_ARRAY_ELEMENTS(in_users)
LOOP
UPDATE words_social SET
social = (t->>'social')::int
WHERE sid = t->>'sid';
IF NOT FOUND THEN
INSERT INTO words_social (social)
VALUES ((t->>'social')::int);
END IF;
END LOOP;
I'm getting this error when trying to run a query that inserts results into a table in sql.
im passing the table name as parameter,how to give the hierarchy value to the insert statement.
here is my code:
declare #pathhere hierarchyid
select #pathhere=Path from SectionDetails where Sectionid=#sectionid and SectionName=#sectionname and Batchid=#batchid and Deptid=#deptid and Schoolid=#schoolid
insert stmt:
set #sqlstmt = 'insert into '+#batch+'(StudentID, StudentName,SectionID,SectionName,BatchID,BatchName, DeptID,DeptName, SchoolID,Path)
values('''+#sectionid+''','''+#sectionname+''','''+#sectionid+''','''+#sectionname+''','''+#batchid+''','''+#batchname+''','''+ #deptid+''','''+#deptname+''', '''+#schoolid+''','+ CAST(#pathhere as hierarchyid)+')'
exec(#sqlstmt)
im getting error in this line:
'+ CAST(#pathhere as hierarchyid)+'
as Invalid operator for data type. Operator equals add, type equals hierarchyid.
can anyone pls help me out how to pass the hierarchy value
You're trying to create a string that can be executed as a statement. So you need to get your hierarchyid into nvarchar(max) instead.
try: #pathhere.ToString()
I have the following JPA SqlResultSetMapping:
#SqlResultSetMappings({
#SqlResultSetMapping(name="GroupParticipantDTO",
columns={
#ColumnResult(name="gpId"),
#ColumnResult(name="gpRole"),
// #ColumnResult(name="gpRemarks")
}
)
Which is used like this:
StringBuilder sbQuery = new StringBuilder("Select ");
sbQuery.append(" gpId, ");
sbQuery.append(" gpRole, ");
// sbQuery.append(" gpRemarks ");
sbQuery.append(" FROM v_group_participants_with_details ");
Query query = em.createNativeQuery(sbQuery.toString(), "GroupParticipantDTO");
The view is like this:
DROP VIEW IF EXISTS `v_group_participants_with_details`;
CREATE VIEW `v_group_participants_with_details`
AS
SELECT
gp.id AS gpId,
gp.role AS gpRole,
gp.remarks AS gpRemarks
FROM GroupParticipation gp
;
The GroupParticipation table has the remarks column defined as LONGTEXT (I'm using Mysql 5.x)
Now for the problem:
When the remarks field is commented out from the query everything works perfectly, but if I try to include the remarks field in the query, I get the following error:
javax.persistence.PersistenceException: org.hibernate.MappingException:
No Dialect mapping for JDBC type: -1
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException
(AbstractEntityManagerImpl.java:614)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:76)
What gives? How can I get a LONGTEXT column from a native query?
This problem is reported in HHH-1483 and HHH-3892. In short, Hibernate does not know, how to map a LONGVARCHAR column returned by a native query.
This problem is fixed in Hibernate 3.5.0+. For previous versions, a workaround would be to extend the MysqlDialect to register the correct Hibernate Type for a LONGVARCHAR:
import java.sql.Types;
import org.hibernate.Hibernate;
public class MyMySQL5Dialect extends org.hibernate.dialect.MySQL5Dialect {
public MyMySQL5Dialect() {
super();
// register additional hibernate types for default use in scalar sqlquery type auto detection
registerHibernateType(Types.LONGVARCHAR, Hibernate.TEXT.getName());
}
}