com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '|' - java

There are two database connection in project.
1. oracle database
2. mssql database
Database connection is OK. Issue is when data transferred/inserted in one database[oracle] then it is display error and same time data inserted in another database[mssql] successfully.Insert query is fine but there is another query which is generate sequesnce number. There have problem.
This is the query which belongs to oracle database
return jdbcTemplate.queryForObject("SELECT 'AK'||LPAD(adds_seq.NEXTVAL,13, '0') adds_seq_no FROM sys.dual ",String.class);
Error is :
SELECT 'AK'||LPAD(adds_seq.NEXTVAL,13, '0') adds_seq_no FROM sys.dual ",String.class ]; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '|'.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
It is working well before when there is no mssql connection.
Below query is for oracle database. When I tried to change code like this:
String sql = " SELECT 'AK'||LPAD(adds_seq.NEXTVAL,13, '0') adds_seq_no FROM sys.dual";
String adSeqNum = null;
try {
adSeqNum = jdbcTemplate.queryForObject(sql, String.class);
} catch (Exception e) {
e.printStackTrace();
}
return addSeqNum;
then the error is
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL []; ORA-01400: cannot insert NULL into ("ADDSS_HST"."ADDS_SEQ_NO")
1.Can you guide me how to solve this issue?
2.Can you please give me example for how to do separate database connection on one java file?

The "Incorrect syntax near '|'" happens because you are sending the Oracle statement "SELECT 'AK'||LPAD(adds_seq.NEXTVAL,13, '0') adds_seq_no FROM sys.dual " to the MSSQL server connection.
The second error, cannot insert null into "ADDSS_HST"."ADDS_SEQ_NO" I suspect happens because before the posted sql that selects from the sequence, you are inserting records into ADDSS_HST table. Is this correct? If so, I recommend that you put the code that generates adds_seq_no into a trigger like the one below (adjust names for your needs):
CREATE OR REPLACE TRIGGER "APPLICATION_BI_TRG"
BEFORE INSERT ON APPLICATION
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
BEGIN
if :new.application_id is null then
// if no value was given in insert statement for column application_id
SELECT APP_WEB_ID_SEQ.NEXTVAL INTO :NEW.application_id FROM dual;
// select a value from sequence into :NEW.application_id
end if;
END;
/

Related

How to create a mySQL stored procedure in a JdbcTemplate

Background
To work around the issue in MySql that certain statements are only permitted within a stored procedure I'm trying to create, run, then drop a stored procedure within sql submitted by a JdbcTemplate. A simplied example would be (this happens to be within spring boot):
#Service
public class StartupDatabaseCheck {
private JdbcTemplate template;
#Autowired
public StartupDatabaseCheck(JdbcTemplate template){
this.template = template;
}
#PostConstruct
public void init() {
log.info("Running custom fields table creation (if required)");
try {
String migrateSql = Resources.toString(Resources.getResource("migrateScript.sql"), Charsets.UTF_8);
template.execute(migrateSql);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Where migrateScript.sql is
DELIMITER //
CREATE PROCEDURE migrate()
BEGIN
IF ((SELECT count(1)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'custom_field_instance_data'
and column_name='entity_id' and is_nullable = false) > 0)
THEN
alter table custom_field_instance_data MODIFY COLUMN entity_id char(32) null;
END IF;
END //
DELIMITER ;
call migrate;
drop procedure migrate;
Running this within mySql workbench works fine, but submitted by the JdbcTemplate I get the error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE PROCEDURE migrate_custom_fields()
As I understand it thats because those DELIMITER statements are not permitted by JdbcTemplate but just removing them as suggested in that link leads to other syntax errors
Question
How can a mySQL stored procedure be created (or statements usually only allowed with a stored procedure be executed) by a JdbcTemplate
Notes
The error without the deliminator statements is
MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE PROCEDURE migrate_custom_fields()
It seems that the driver is not taking the delimited queries into the account.If you want to create an stored procedure on fly using the jdbc.
Using the following property and pass it as the connection parameter in the URL.
jdbc:mysql://localhost:3306/test?allowMultiQueries=true
The above property will allow ';' delimited queries.
You can find more on this at here
Create MySQL stored procedure using JPA Hibernate
The updated migrateScript.sql in this case would be
drop procedure IF EXISTS migrate_custom_fields;
CREATE PROCEDURE migrate_custom_fields()
BEGIN
IF ((SELECT count(1)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'custom_field_instance_data'
and column_name='entity_id' and is_nullable = false) > 0)
THEN
alter table custom_field_instance_data MODIFY COLUMN entity_id char(32) null;
END IF;
END ;
call migrate_custom_fields;
drop procedure migrate_custom_fields;

sql query returning 0 rows

I have this sql query which runs fine and return 3 rows when run on sql developer but when I execute the same query in a jsp page, it executes properly but doesn't return any rows. There is no problem with database connection because all other queries work fine.
Server - Tomcat 7
database - Oracle 10g
query -
select slno from lbk_tab where log_date = to_date('18-06-2017','DD-MM-YYYY')
jsp -
String dtol = "select slno from lbk_tab where log_date = to_date('18-06-2017','DD-MM-YYYY')";
Statement st = connection.createStatement();
ResultSet resultSet = st.executeQuery(dtol);
if (resultSet.next()) {
out.print(Integer.parseInt(resultSet.getString(1)));
}
Table lbk_tab has columns slno and log_date.
How can I fix this?
Try these things :
Classfiles are being generated afresh ? Clear & re-build project /
workspace.
Print the query and try to run printed query. Theoretically it looks the same from code, but just to be sure..
Check for query being fired at database also, may be java messes
with date object or date format. Hence the actual date fired from jsp says something else while fired at mysql points at something else ? debug / log / print query actually fired at mysql
end.
More clarity is required here, "to_date" referenced in query is
function ? what are column types.
I Think you need to use to_char()
select slno from lbk_tab where log_date = to_char(to_date('18-06-2017','DD-MM-YYYY'))

JDBC MSSQL Insert fails with error "near where"

I have a strange problem. I'm executing insert using prepared statement like this:
try (Connection connection = connectionPool.getConnection();
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { //TODO: caching of PS
int i = 1;
ParameterMetaData pmd = ps.getParameterMetaData();
...
} catch (SQLException e) {
throw new TGFIOException("Error executing SQL command " + sql, e);
}
Insert statement is like this:
insert into dbo.CurrencyRates(RateDate, CurrencyID, Rate) values ( ?, ?, ? )
Unfortunately it fails with following exception:
com.microsoft.sqlserver.jdbc.SQLServerException: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'WHERE'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
at com.microsoft.sqlserver.jdbc.SQLServerParameterMetaData.<init>(SQLServerParameterMetaData.java:426)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.getParameterMetaData(SQLServerPreparedStatement.java:1532)
at com.jolbox.bonecp.PreparedStatementHandle.getParameterMetaData(PreparedStatementHandle.java:246)
There is no WHERE in the statement, so I am puzzled why it fails on metadata extraction...
EDIT:
SQL Server = 10.50.2500.0 Express Edition,
Driver = sqljdbc4.jar from 4.0 package
Also, I am using getParameterMetaData because I need to set some params to null and the preferred method is to use setNull() where you need SQLType.
EDIT2:
I've tested with Driver sqljdbc41 from newest 6.0 package - results are the same
EDIT3:
I've removed call to getParameterMetaData() and it worked, unfortunately it is a generic part that should max portable, yet it does not work with this single table (inserts to other tables on the same database works fine !!!)
EDIT4:
I've tried with different insert statements for this table and all of them works fine if I skip ps.getParameterMetaData() and fail when I call it. If I try with 2 or more params I get usual near WHERE error. If I try one column insert I get an error stating that the column name is incorrect, even if it is correct and without the meta data call it works perfectly fine. I will try to trace what driver tries to do underneath...
After some tracing on what actually the driver does (many thanks a_horse_with_no_name), I've come to some funny conclusion.
The solution for my question is to:
Replace following insert statement
INSERT INTO CurrencyRates(RateDate, CurrencyID, Rate) VALUES ( ?, ?, ? )
With this statement
INSERT INTO CurrencyRates (RateDate, CurrencyID, Rate) VALUES ( ?, ?, ? )
Logic behind that is that SQL driver does some metadata extraction in the background, and it creates a query with following fragment: ... FROM CurrencyRates(RateDate WHERE ... if you do not put space after table name, yet for the ordinary call this is perfectly possible!
EDIT:
This is obviously an inconsistency as (putting aside what actually is a valid insert) it should consistently accept or reject this query no matter if I call for meta data or not.

Issue with exporting portgresql table to CSV in JDBC

I'm using postgresql to host my database. In my database, I have a table say xyz whose structure is as shown below
id content folder
1 hello Inbox
2 hi Sent
I want to export this table to CSV using my java program. The code snippet is below
Connection connection2 = new ServerDBConnect().getConnection();
PreparedStatement statement = connection2.prepareStatement("copy (SELECT * FROM xyz WHERE folder=? ) to 'C:/export.csv' delimiter ','");
statement.setString(1, FOLDER_SELECTED); //Here, FOLDER_SELECTED=Inbox
statement.execute();
When I execute this code, I'm getting SQLException saying
ERROR: there is no parameter $1
If I execute the code without folder specified ("copy (SELECT * FROM xyz) to 'C:/export.csv' delimiter ','")), the code works fine.
What am I doing wrong here? How to go about this problem?
Note: If I execute the query (copy (SELECT * FROM xyz WHERE folder='Inbox' ORDER BY time) to 'G:/export.csv' delimiter ',') directly in the Postgresql SQL console, I'm getting the desired output.
Please help
Ah
I finally found the answer myself.
Small change in the query gave me the desired result
The query is suppose to be like this
Connection connection2 = new ServerDBConnect().getConnection();
PreparedStatement statement = connection2.prepareStatement("copy (SELECT * FROM xyz WHERE folder='" + FOLDER_SELECTED + "' ) to 'C:/export.csv' delimiter ','");
This was driving me crazy, but finally done :-)

JTDS (Java/MSSQL) - Could not find Stored Procedure

I am using JTDS with Java to connect to a Microsoft SQL database. I am able to connect to the database perfectly. However when I run the code below, I am getting an error "Could not find stored procedure 'get_queue_items' ". I've tried prefixing 'dbo.' to the stored procedure name, however I continue to get the error. I've also included the actual stored procedure for reference.
try {
// Prepare and call the stored procedure
CallableStatement proc = connection.prepareCall("{call get_queue_items(?) }");
// Register the ResultSet
proc.registerOutParameter(1, java.sql.Types.INTEGER);
// Register Input Parameters
proc.setInt("#last_queue_entry", 1);
// Execute the stored procedure
proc.execute();
// If we have a ResultSet
if (proc.getMoreResults()) {
ResultSet rs = proc.getResultSet();
if (rs.next()) {
// to complete...
}
}
}
catch(Exception ex)
{
System.out.println("Error: " + ex.getMessage());
}
And the stored procedure:
USE [test]
GO
/****** Object: StoredProcedure [dbo].[get_queue_items] Script Date: 11/17/2011 11:43:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[get_queue_items] #qid int OUT, #last_queue_entry int as
-- select all the new records out of the main table into a temp table
-- the temp table is what we will use to process
select #qid = qid from test.[dbo].que_items
where qid > #last_queue_entry
I'm new to JTDS and Java, so its likely I am at fault, but any help would be appreciated.
Edit: Changed the Stored Procedure as per Cristian's advice, still getting the same error 'Could not find stored procedure 'get_queue_items'
Edit 2: Still not working - database connectivity seems fine also.
Today I met same problem and it seems to me that there is a bug in jTDS implementation. For me solution was procedure renaming and removing all underscore symbols (that is getQueueItems(?) in your case). Try, I think it must help to you.
you have to specify the output parameters, there are certain parameters that can not be specified as: text, ntext, and image.
ALTER procedure [dbo].[get_queue_items] #id int OUT, #last_queue_entry int as
-- select all the new records out of the main table into a temp table
-- the temp table is what we will use to process
select #id = id from test.[dbo].que_items
where qid > #last_queue_entry
this prodecure will return only id numbers

Categories

Resources