I've searched stackoverflow but did not found the solution (at least the way I want it).
I have a JSP page which calls a Java method to insert a date into Oracle database.
It passes a String.
The problem, how to build the string to execute the insert?
String myInsert = "INSERT INTO table_name
values (..., to_date(<<Java variable name>>, 'yyyy/mm/dd hh:mm'), ....);
where Java variable name refers to a variable of type String.
I want to let Oracle to the job, not necessarily using SimpleDateFormat, if it's possible. So, should I use '' or " "
Youre help would be very much appreciated
You should use a PreparedStatement along with its setDate function and not deal with date to string conversions yourself.
See http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#setDate(int,%20java.sql.Date)
String myInsert="INSERT INTO table_name values(...?)";
PreparedStatement ps=connection.prepareStatement(myInsert);
ps.setDate(1,<<java variable name>>);
...
Related
I’m struggling to insert a JSON object into my postgres v9.4 DB. I have defined the column called "evtjson" as type json (not jsonb).
I am trying to use a prepared statement in Java (jdk1.8) to insert a Json object (built using JEE javax.json libraries) into the column, but I keep running into SQLException errors.
I create the JSON object using:
JsonObject mbrLogRec = Json.createObjectBuilder().build();
…
mbrLogRec = Json.createObjectBuilder()
.add("New MbrID", newId)
.build();
Then I pass this object as a parameter to another method to write it to the DB using a prepared statement. (along with several other fields) As:
pStmt.setObject(11, dtlRec);
Using this method, I receive the following error:
org.postgresql.util.PSQLException: No hstore extension installed.
at org.postgresql.jdbc.PgPreparedStatement.setMap(PgPreparedStatement.java:553)
at org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:1036)
I have also tried:
pStmt.setString(11, dtlRec.toString());
pStmt.setObject(11, dtlRec.toString());
Which produce a different error:
Event JSON: {"New MbrID":29}
SQLException: ERROR: column "evtjson" is of type json but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
But, at least this tells me that the DB is recognizing the column as type JSON.
I did try installing the hstore extension, but it then told me that it was not an hstore object.
OracleDocs shows a number of various methods to set the parameter value in the preparedStatement, but I'd rather not try them all if someone knows the answer. (http://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html) These also reference an additional parameter, SQLType, but I can't find any reference to these.
Should I try setAsciiStream? CharacterStream? CLOB?
This behaviour is quite annoying since JSON strings are accepted without problems when used as literal strings in SQL commands.
There is a already an issue for this in the postgres driver Github repository (even if the problem seems the be the serverside processing).
Besides using a cast (see answer of
#a_horse_with_no_name) in the sql string, the issue author offers two additional solutions:
Use a parameter stringtype=unspecified in the JDBC connection URL/options.
This tells PostgreSQL that all text or varchar parameters are actually
of unknown type, letting it infer their types more freely.
Wrap the parameter in a org.postgresql.util.PGobject:
PGobject jsonObject = new PGobject();
jsonObject.setType("json");
jsonObject.setValue(yourJsonString);
pstmt.setObject(11, jsonObject);
You can do it like this and you just need the json string:
Change the query to:
String query = "INSERT INTO table (json_field) VALUES (to_json(?::json))"
And set the parameter as a String.
pStmt.setString(1, json);
You have two options:
Use statement.setString(jsonStr) and then handle the conversion in the sql statement:
PreparedStatement statement = con.prepareStatement(
"insert into table (jsonColumn) values (?::json)");
statement.setString(1, jsonStr);
Another option is to use PGobject to create a custom value wrapper.
PGobject jsonObject = new PGobject();
PreparedStatement statement = con.prepareStatement(
"insert into table (jsonColumn) values (?)");
jsonObject.setType("json");
jsonObject.setValue(jsonStr);
statement.setObject(1, jsonObject);
I personally prefer the latter as the query is cleaner
Passing the JSON as a String is the right approach, but as the error message tells you, you need to cast the parameter in the INSERT statement to a JSON value:
insert into the_table
(.., evtjson, ..)
values
(.., cast(? as json), ..)
Then you can use pStmt.setString(11, dtlRec.toString()) to pass the value
Most answers here defines ways of inserting into postgres json field with jdbc in a non-standard way, ie. it is db implementation specific. If you need to insert a java string into a postgres json field with pure jdbc and pure sql use:
preparedStatement.setObject(1, "{}", java.sql.Types.OTHER)
This will make the postgres jdbc driver (tested with org.postgresql:postgresql:42.2.19) convert the java string to the json type. It will also validate the string as being a valid json representation, something that various answers using implicit string casts does not do - resulting in the possibility of corrupt persisted json data.
As others have mentioned, your SQL string needs to explicitly cast the bind value to the PostgreSQL json or jsonb type:
insert into t (id, j) values (?, ?::json)
Now you can bind the string value. Alternatively, you can use a library that can do it, for example jOOQ (works out of the box) or Hibernate (using a third party UserType registration). The benefits of this is that you don't have to think about this every time you bind such a variable (or read it). A jOOQ example:
ctx.insertInto(T)
.columns(T.ID, T.J)
.values(1, JSON.valueOf("[1, 2, 3]"))
.execute();
Behind the scenes, the same cast as above is always generated, whenever you work with this JSON (or JSONB) data type.
(Disclaimer: I work for the company behind jOOQ)
if using spring boot: adding the following line to application.properties helped:
spring.datasource.hikari.data-source-properties.stringtype=unspecified
as Wero wrote:
This tells PostgreSQL that all text or varchar parameters are actually
of unknown type
Instead of passing json object pass its string value and cast it to json in the query.
Example:
JSONObject someJsonObject=..........
String yourJsonString = someJsonObject.toString();
String query = "INSERT INTO table (json_field) VALUES (to_json(yourJsonString::json))";
this worked for me.
DELIMITER //
CREATE PROCEDURE temp ( empId INT)
BEGIN
DECLARE var_etype VARCHAR(36);
SELECT
emptype = QOUTE(emptype)
FROM
dms_document
WHERE
id = empid;
SELECT
emptype,
CASE
WHEN emptype = 'P' THEN doctype
ELSE 'No Documents required'
END
FROM
dms_report
WHERE
pilot = 1;
End//
DELIMITER ;
I have created this procedure successfully but when I try to call it, I am getting error 1305 the function database.temp does not exist. I am trying to call using this statement:
SET #increment = '1';
select temp( #increment)
but I get Error, please tell me where I made mistake.
This is how you call it, use use the keyword call and then procedure's name
call procedureName(params);
in call of making an string
String sqlString = "procedureName("+?+")"; //in case of Integers
String sqlString = "procedureName('"+?+"')";//in case of Integers
bring the parameter in prepared statement.
MySQL's documentation on Using JDBC CallableStatements to Execute Stored Procedures explains the necessary steps quite well.
This is what your java code needs to look like:
CallableStatement cStmt = conn.prepareCall("{call temp(?)}");
cStmt.setInt(1, 42); //set your input parameter, empId, to 42.
If you want to work with the rows returned by your stored procedure's query in your Java code, you're also going to need to create an OUT parameter as noted in MySql's documentation page titled, CALL Syntax:
CALL can pass back values to its caller using parameters that are
declared as OUT or INOUT parameters
In order to call your stored procedure from MySQL workbench, use the CALL command. You can call stored procedure by directly setting values for each of the parameters:
SET #increment = 1;
CALL temp(#increment)
Then you simply use the SELECT statement to return the value of your output parameter
SELECT #outParameter
With help setting your output parameters, please read the article MySQL Stored Procedure - SELECT - Example.
Your stored procedure is syntactically wrong, and as mentioned in the comments, you're not using the stored procedure functionality for it's intended use. It's intended to be used for data manipulation not for querying. You should instead consider turning your procedure into a series of prepared statements.
Please let me know if you have any questions!
I am using PreparedStatement's setString method to set values for the start and end dates in a sql query.
String sql = "..... " AND tableA.time BETWEEN ? " +
" AND ?";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, startDate);
st.setString(2, endDate);
The values however are not being set. I understand that normally there is an equals sign:
"tableA.member_id = ?" +"
How do I than call setString method when I am using a 'Between' operator in the sql statement? Hope someone can advise. Thank you.
See http://docs.oracle.com/cd/B28359_01/server.111/b28286/conditions011.htm
"BETWEEN" can be used with datetime data types. However, if tableA.time is a datetime field of some kind (Timestamp, etc.), using st.setString(...) won't work. You need to use setDate(dt) or setTimestamp(ts) instead. See Using setDate in PreparedStatement for more info.
Use setDate.
Is your startDate and endDate a java.util.Date object?
If it is, you can use this code.
st.setDate(1, new java.sql.Date(startDate.getTime()));
st.setDate(2, new java.sql.Date(endDate.getTime()));
If it is not. Convert that first ro java.util.Date object.
BETWEEN expects its arguments to have a type that is compatible with the column being tested. Giving it string arguments for a date column won't work.
You could add a function to the SQL in order to convert the string to a date (I don't know what database you're using, this example uses Oracle's to_date function):
from tableA.time BETWEEN to_date(?, 'yyyy/mm/dd') AND to_date(?, 'yyyy/mm/dd')
Alternatively you could leave the SQL alone and use setDate on the PreparedStatement, like:
setDate(1, new SimpleDateFormat("yyyy/MM/dd").parse(startDate));
This second way is more usual, it has the advantage of avoiding having to add a date-conversion function (that may be non-standard) to your SQL.
But you would have to do the conversion on one side or the other. The database's SQL parser won't convert it for you. If the database took responsibility for the conversion and there was a mistake it could introduce data errors silently, the less error-prone alternative is for the application developer to tell the database how the date string should be converted.
I have a SQL statement and trying execute with H2 in-memory database in Java. The following exception thrown.
SQL:
SELECT ACCT_RULE_ID, ACCT_ACTION_ID
FROM ACCT_RULE
WHERE (ACCT_ACTION_ID = ?)
AND (START_DATETIME <= to_char(?, 'mm/dd/yyyy HH:MI:SS AM'))
AND (STOP_DATETIME > to_char(?, 'mm/dd/yyyy HH:MI:SS AM'))
Replacing first parameter with Id and second and third parameter with new Date() value.
Exception:
Caused by: org.h2.jdbc.JdbcSQLException: Function "TO_DATE" not found; SQL statement:
you should be able to create your own to_date function
drop ALIAS if exists TO_DATE;
CREATE ALIAS TO_DATE as '
import java.text.*;
#CODE
java.util.Date toDate(String s, String dateFormat) throws Exception {
return new SimpleDateFormat(dateFormat).parse(s);
}
'
Of course you could also just use parsedatetime() per David Small's answer
One way to remove the time portion from a date-time field in H2, is to format the field as a string and then parse it. This worked for me:
PARSEDATETIME(FORMATDATETIME(field_name, 'yyyy-MM-dd'), 'yyyy-MM-dd')
H2's parse and format date functions follow the java.text.SimpleDataFormat semantics.
Yes, it is NOT super optimized. This is fine for our needs since we only use H2 for unit tests.
H2 database does not have TO_CHAR() function. But H2 database does have sysdate, dual, varchar2 which makes writing oracle query that will run on H2 database quite easy. So you can write a function instead which will H2 database function alias for making it handle date/timestamp with format. TO_CHAR(sysdate, 'DD/MM/YYYY HH24:MI:SS') can be used in H2 database.
Despite the lack of documentation there are TO_DATE function in PostgreSQL compatibility mode since 2.0.204.
Changelog ticket
i replace a particular string in a statement like the following
SQL = SQL.replaceAll("CUSTOMER_NUMBER", customer);
this conversion goes as integer but i want to replace this as a string like the following
AND CIMtrek_accountlist_customer_number = '0002538'
but at present it replaces like the following
AND CIMtrek_accountlist_customer_number = 0002538
how to do this in java.
Just get it to output the ' as well as the customer variable
SQL = SQL.replaceAll("CUSTOMER_NUMBER", "'" + customer + "'");
However as #jlordo mentioned in a comment, you should look at using prepared statements which will allow you to inject values into a prepared sql statement.
Though you should be using PreparedStatement if you are running SQL, However if placeholder "CUSTOMER_NUMBER" is under your control, It is better to use String.format. See and example here