When I run the sql statement below through psql it works fine, but when I try to run the same query by building it with a preparedstatement, it fails.
INSERT INTO Hvbp
(provider_number, weighted_clinical_process,
weighted_patience_experience, total_performance_score,
coordinates, latitude, longitude, address, city, state, zip)
VALUES
('010092', 43.909090909091, 13.5, 57.409090909091,
'POINT(33.206201 -87.525480)', 33.206200613000476,
-87.52548020899968, '809 UNIVERSITY BOULEVARD EAST', 'TUSCALOOSA', 'AL', '');
The error I keep getting is
org.postgresql.util.PSQLException: ERROR: column "coordinates" is of type geography but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 203
The coordinates column is of type GEOGRAPHY(POINT)
I know this is an old problem, but I just spend most of the day debugging the same basic problem and finally found a fix
What you're trying to do, is provide the POINT using WKT and have the server automatically convert that into a Geometry.
And as you've found that works if you include the WKT inside the body of the SQL, but fails if you use a parameter on a prepared statement.
There are 3 options for fixing it:
Use st_GeographyFromText in your SQL like so:
INSERT INTO Hvbp(coordinates) VALUES( st_GeographyFromText(?) )
And then set your parameters as WKT with setString.
Depending on the frameworks involved, that might not be possible for you.
Use setObject on the preparedStatement instead of setString. For example:
ps.setObject(1, "POINT(33.206201 -87.525480)", java.sql.Types.OTHER )
Change your JDBC driver settings to send strings as unspecified type, and then the server will do type conversions for you. To do that you want to change your JDBC URL to something like
"jdbc:postgresql:my_db?stringtype=unspecified"
#Tim - thank you for your help with a similar problem - I had to write ST_GeometryFromText into my database and the JDBC Driver threw a similar exception as #Hanks got.
For further reference and clarification for others - this is my result using Java with JDBC:
INSERT INTO streets.points ( point_id, the_geom )
VALUES( ?, ST_GeomFromText( ? , 25832) );
And the inserted Geometry-String looked like that:
POINT(33.206201 -87.525480)
Related
I have a very simple SQL query I need to run
SELECT `id`, `{Document id}` FROM `test`.`test` LIMIT 10;
where {Document id} is a column name. Whenever I run it through MariaDB JDBC, it fails with error unknown escape sequence. From my understanding {CALL ...} is used to call stored procedure with a JDBC CallableStatement.
How do I escape it? I want JDBC to treat it as literal string without special meaning. \ didn't work for me.
As mentioned in deleted answer by #a_horse_with_no_name, there is setEscapeProcessing. But it's not supported by a lot of connectors (example MariaDB).
I have confirmed this issue using mariadb-java-client-2.2.5. It is not an issue with mysql-connector-java-5.1.44 so you might want to report this issue to MariaDB.
Following the suggestion by #JoopEggen in the comments above, I got it to work with MariaDB JDBC by adding sessionVariables=sql_mode=ANSI_QUOTES to the connection string and using
ResultSet rs = st.executeQuery("SELECT \"{Document id}\" FROM test.test");
I am working with some legacy code that performs database operations in a generic way, so that the User/developer can work with a different database by changing only the JDBC driver.
I have a problem with PostgreSQL JDBC driver. My test case:
//ddl
CREATE TABLE test
(
id numeric,
name text,
)
//java code
String sqlCmd = "INSERT INTO test values (?, ?)";
PreparedStatement ps = connection.prepareStatement( sqlCmd );
ps.setString( 1, "1" );
ps.setString( 1, "name1" );
ps.executeUpdate();
With Postgres, the result of this case is an exception with message: "can't cast string to int..."
Is it inappropriate to use PreparedStatement.setString() to set values that database expects to be numeric?
Should I expect the JDBC driver to automatically convert java types to database types?
This test passes with other databases, including H2 and MySQL. Does the failure with PostgreSQL reflect a bug in the JDBC driver? Is it possible to make this case work without changing code?
The documentation for java.sql.PreparedStatement has this to say:
Note: The setter methods (setShort, setString, and so on) for setting IN parameter values must specify types that are compatible with the defined SQL type of the input parameter. For instance, if the IN parameter has SQL type INTEGER, then the method setInt should be used.
Whether a particular database or JDBC driver allows you to be sloppy about that is its own affair, but you are not justified in expecting that all drivers will allow such slop, even if certain ones do.
while migrating from oracle database to postgresql, I found that may help you to use setString with numeric types and date types as well.
Just you have to use the connection parameter stringtype=specified as mentioned in the documentation.
https://jdbc.postgresql.org/documentation/head/connect.html
You are using setString() method to insert integers and postgres could not do that, Use
ps.setInt(1, INTEGER_VALUE);
I want to insert null data to Teradata with JDBC connection on JAVA.
First of all I try this:
PreparedStatement stmt;
String qm="Insert into db.user values (?,?,?,?,?,?,?)";
connection= DriverManager.getConnection
(
"jdbc:teradata://192.xxx.x.xx/database=DBC,tmode=ANSI,charset=UTF8","user","passw0rd" );
stmt = connection.prepareStatement(qm);
//some code here to open while loop
stmt.setObject(i,null); // This isnt working with Terada JDBC. It is working for Oracle and MSSQL JDBC
//and I finish my code
And after, that I tried this instead of stmt.setObject(i,null); :
stmt.setNull(i,rsmd.getColumnType(i),rsmd.getColumnTypeName(i));
rsmd.getColumnType(i) is equal to 97
rsmd.getColumnTypeName(i) is equal to DATE
Yes it is true my field is DATE.
But it gives this ERROR:
ERROR : [Teradata JDBC Driver] [TeraJDBC 14.10.00.17] [Error 857] [SQLState HY000] Two different data types are being set for parameter 17 (449 & 749)
How can I fix this.
I used in the past the setNull(i, Types.#field type#) in a custom DB layer for TD.
However if you search the codes returned in the exception you'll find that they represent a Date and a Varchar, as if, at the same position, you sometimes pass a Date type and sometimes a Varchar.
Are you by chance passing not null dates as Date-like strings (e.g. "2015-08-18"), and not as java.sql.Date objects?
If that's the case you should change the code to use java.sql.Date objects and this will solve your issue.
Typically if you wish to INSERT a NULL value into ColC I would suggest using the following method with your INSERT ... VALUES statement:
INSERT (ColA, ColB, ColD, ColE) VALUES (1000, 'Testing Null', 1.00, DATE '2013-06-30);
Teradata will take the absence of the column in the INSERT statement to place either the pre-defined DEFAULT value or NULL for the column.
What if you try the following:
stmt.SetNull(i,Types.NULL)
The workaround for this issue is to cast the NULL to be a VARCHAR, so that it is compatible.
INSERT INTO XYA(PKEY,REF_KEY) VALUES(2,cast(null as varchar(10)));
I'm trying to track the amount of redo being generated during a database session with the following query:
SELECT a.name, b.VALUE
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic# AND a.name = 'redo size';
This query works directly in SQL*Plus and Toad, but I get an ORA-00911 exception using JDBC, and I've narrowed it down to the "statistic#" column name.
How do I get around this?
The column name statistic# is not the problem.
My bet is that you also send the terminating ; from inside your Java program.
But you may not include the the ; when executing a SQL statement through JDBC (at least not in Oracle and some other DBMS).
Remove the ; from your SQL String and it should be fine.
put it in double quotes - that should let you call a field anything in Oracle
Switch on JDBC logging, check your driver documentation for how to do this. In the JDBC log you see the actual statement prepared and executed in the DB. This eliminates one possible cause for the error.
I’m working on a Java server app which uses Spring 3 and C3P0 to access a Microsoft SQL Server 2008 R2 database, using version 3.0 of Microsoft’s JDBC 4 driver.
I have a sproc which has an input defined like so:
#modifiedAfter datetime = NULL
I’m using Spring to construct a call to this sproc.
I’m constructing a MapSqlParameterSource to contain my parameters:
MapSqlParameterSource in = new MapSqlParameterSource()
in.addValue("modifiedAfter", "2011-01-01T00:00:00", Types.TIMESTAMP)
But when I execute the call:
this.sprocCall.execute(in);
I get this:
com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string
…and I have no idea why.
I’ve tried a few variations on adding the parameter, such as passing it in as a Date, or specifying it as a VARCHAR, or not specifying the type — none of them work.
I’m beginning to suspect that the problem might be related to Spring. I wrote a little Groovy script to try to isolate the problem, and this works just fine:
dt = new DateTime("2012-02-01T00:00:00") // Joda DateTime
println sql.rows("exec spMySproc #modifiedAfter=${Sql.TIMESTAMP(dt.toString())}")
…but when I try the equivalent approach with MapSqlParameterSource, I get the above error.
At this point, I’m stumped.
Here’s the top of the stacktrace:
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call spGetPoliciesCatalogPaged(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}]; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:952)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:985)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:368)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:342)
at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:164)
… which is followed by some of my classes, then this:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:197)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4762)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1682)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:955)
at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:2859)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:91)
at org.springframework.jdbc.core.JdbcTemplate.processResultSet(JdbcTemplate.java:1124)
at org.springframework.jdbc.core.JdbcTemplate.extractReturnedResults(JdbcTemplate.java:1023)
at org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:995)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:936)
... 68 more
I tried updating to the latest version of spring-jdbc, 3.1.1, but it did not help.
I’d appreciate any help at all!
Thanks,
Avi
A co-worker of mine figured this out. It turns out that I had jumped the gun by blaming Spring and/or the Microsoft SQL Server driver. The problem was indeed an error when converting a character string to a date/time — but it wasn’t a problem directly with my parameter, it was a problem with a query that was being run by the dynamic SQL generated by my sproc, if I passed in this parameter.
The problematic code looks something like this:
IF #modifiedAfter IS NOT NULL BEGIN
SET #SQL = #SQL + N'AND mytable.ThingLastUpdated > #modifiedAfter'
END
Once the dynamic SQL contained in #SQL was actually executed, the contents of #modifiedAfter — a perfectly valid DATETIME, sent in from my Java code with no issues at all — were compared with the contents of mytable.ThingLastUpdated — which was a VARCHAR column which meant that SQL Server had to convert its contents to DATETIME so that they could be compared to #modifiedAfter — but not all values in mytable.ThingLastUpdated could be successfully converted, hence the conversion error being thrown.
The fix I decided on was to change the type of mytable.ThingLastUpdated to DATETIME, and do any needed conversion at insertion time, which I think will be more efficient than doing so at query time.
Lesson learned: if a SQL problem isn’t in my Java code, it’s probably in my SQL — not in Spring or a JDBC driver. PEBKAC.
How about passing the input as String/varchar and then converting it to datetime in the sproc?
This error is defenitely not a SQL problem bacause it converts that string "2011-01-01T00:00:00" to datetime successfully. The sql parameter type you have declared is of type TIMESTAMP and you are passing a string. I think that is where it fails to convert.
Try declaring the sql parameter type as string or varchar instead of TimeStamp.
Had a similar problem in and was looking # MSDN and looks like Sql-Server 2005 had a bug with precision conversion. Supposedly the version you are using has bumped up the precision 100ns. Will it be possible verify if the time-stamp precision. Here is the link for the discussion: Sql Server Conversion error