H2 database throwing an unexpected JdbcSQLException on CREATE SEQUENCE - java

I am trying to write an in-memory database in order to test my DAO objects. I get the following stack trace :
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement " CREATE SEQUENCE CE0AOFQ AS[*] BIGINT START WITH 1 INCREMENT BY 1"; SQL statement:
CREATE SEQUENCE CE0AOFQ AS BIGINT START WITH 1 INCREMENT BY 1 [42000-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.message.DbException.getSyntaxError(DbException.java:191)
at org.h2.command.Parser.getSyntaxError(Parser.java:534)
at org.h2.command.Parser.prepareCommand(Parser.java:261)
at org.h2.engine.Session.prepareLocal(Session.java:578)
at org.h2.engine.Session.prepareCommand(Session.java:519)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1204)
at org.h2.jdbc.JdbcStatement.executeUpdateInternal(JdbcStatement.java:132)
at org.h2.jdbc.JdbcStatement.executeUpdate(JdbcStatement.java:121)
at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.executeSqlScript(ResourceDatabasePopulator.java:169)
When trying to execute this command into a file called init.sql:
CREATE SEQUENCE CE0AOFQ AS BIGINT START WITH 1 INCREMENT BY 1;
As far as I checked (here, for example), this query seems correct.
Any idea why this is not working ?

You cannot specify the datatype of a sequence in h2. It is always BIGINT.
Use:
CREATE SEQUENCE CE0AOFQ START WITH 1 INCREMENT BY 1;

For anyone struggling (like me) with H2 databse syntax, follow lance-java's advice and read the actual H2 grammar documentation. You may find good advices, for example:
Creates a new sequence. The data type of a sequence is BIGINT. Used values are never re-used, even when the transaction is rolled back.
Which means you cannot change it.

Related

Spring Boot schema.sql, initializing database using PL/SQL

I am working on a project where I have to use Oracle Database 12c and I have to write all queries manually (so I can't use Spring Data).
For creating all tables and relationships, I use schema.sql and for template data I use data.sql.
And I have a problem with checking if table or data already exists.
In MySQL creating table would be like "create table if not exists".
In PL/SQL unfortunately, there is no equivalent for "if not exists". I replaced this functionality by:
begin
execute immediate
'CREATE TABLE user_data (
some data
)';
exception when others then if SQLCODE = -955 then null; else raise; end if;
end;
And it works when I run this script in SQL Developer or in Intellij's SQL console but the problem occurs when I want to run an application and Spring Boot tries to execute a script from schema.sql.
Output in terminal tells that:
nested exception is java.sql.SQLException: ORA-06550: line 8, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem return
returning <an exponent (**)> <> or != or ~= >= <= <> and or
like like2 like4 likec between into using || multiset bulk
member submultiset
So it looks like Spring Boot doesn't know that it should run statement between "begin" and "end".
Any idea how can I manage the problem with database initialization ?
As a workaround, I could drop tables with every application run but it is not an optimal solution (and it wouldn't work when someone run the application for the first time).
Firstly, I would like to share two topics that seem to be relevant to this problem:
Unable to use "DROP TABLE IF EXISTS" in schema.sql for a Spring Boot application
executeSqlScript fails with Spring for PL/SQL block
There you will find a solution that should work: create a stored procedure and use in your schema.sql statement like
call recreate_table('USER_DATA','CREATE TABLE USER_DATA (SOME DATA)');
CALL statement is widely used across different databases, shortened to statement with only one semicolon and thus works well.
Secondly, I may only suppose, that the main problem is that anonymous blocks in PL/SQL (as well as other complex enough statements that may contain more than one semicolon) should be finished by a / character. I would recommend you to try to append this character to the end of your script, take a look at this and this answers, and if it does not work, create a stored procedure.
Also note that there is another way to check existence of the table (that comes over this wait for an exception pattern):
select count(*)
from user_tables t
where t.table_name = 'USER_DATA'
and rownum < 2

JDBC Error : java.sql.SQLException: ORA-08002: sequence is not yet defined in this session

Below is my sequence that i created :
CREATE SEQUENCE SEQ_SURVEY INCREMENT BY 1 START WITH 1 NOCACHE NOCYCLE ;
in my JDBC Code, I am using :
String currentValueFromSequence = "SELECT SEQ_SURVEY.CURRVAL FROM DUAL";
PreparedStatement getCurrValFromSeq = con.prepareStatement(currentValueFromSequence);
ResultSet getSurveyResponseID = getCurrValFromSeq.executeQuery();
Its throwing an error stating that :
java.sql.SQLException: ORA-08002: sequence SEQ_SURVEY.CURRVAL is not yet defined in this session
I am not able to understand why this code is not running in my QA Environment whereas this code ran perfectly fine in my Dev Environment.
Can any expert provide their suggestion ?
You need to call NEXVAL first. That's why you are getting the error.
SELECT SEQ_SURVEY.NEXTVAL FROM DUAL
The Oracle NEXTVAL function is used to retrieve the next value in a sequence. The Oracle NEXTVAL function MUST BE called before calling the CURRVAL function, or an error will be thrown. The Oracle CURRVAL function is used to access the current value of the specified sequence. Note that CURRVAL can only be used if NEXTVAL has been referenced in the current user session at least once.

Create table if not exists in DB2

In DB2 we want to check if a table exists or not and depending on that we want to create the table. I searched on the net and I always find the same anwser, but I keep getting an error when I want to run the query.
begin
declare continue handler for sqlstate '42710' begin end;
execute immediate 'CREATE TABLE HTMLMONIDB.DLW_C(MSG_ID varchar(119) NOT NULL, DIRECTION varchar(8) NOT NULL, TO_PARTY_NAME varchar(60) NOT NULL, PRIMARY KEY CLUSTERED (MSG_ID ASC, DIRECTION ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]';
end
I keep getting the same error over and over.
java.security.PrivilegedActionException: java.sql.SQLSyntaxErrorException: [SQL0104] Token 'CREATE TABLE SHEMA.TABLENAME was not valid. Valid tokens: : <IDENTIFIER> <PLI_STRING>
Not sure what the error means, so any help is appreciated!
Thanks!
The problem is with your create table syntax.
This doesn't appear to resemble valid DB2 syntax. Instead, it looks a lot like SQL Server syntax. Consult the documentation for your specific version of DB2.
In terms of debugging this problem, you should first get a create table statement working directly in an SQL client before trying to put it in dynamic SQL. Then you should get your compound SQL statement working before trying to incorporate it into Java.

Syntax error on Java PreparedStatement.setBytes with mysql

I'm trying to set a BLOB mysql field with the PreparedStatement.setBytes method.
The problem is that the query ends up with a string containing the bytes to be inserted.. more or less.
So, here is the code where it's about:
PreparedStatement stmt = this.getStatement( "UPDATE TABLE users SET logintoken=? WHERE qrid=?" );
stmt.setBytes( 1, token );
stmt.setString( 2, bar.getId() );
stmt.execute();
For the record, token is a byte[] always holding 20 bytes generated by SecureRandom
And here is 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 'TABLE users SET logintoken=x'6DA9D5137B059AE6BCFE7F170693A76CA6484FFB24963BF88AA' at line 1
As you can see, it places an x' at the beginning of the data.
Logically this breaks the query since part of the data is not contained within the string.
I assumed that the PreparedStatement.setBytes would solve the problem but it does not.
I've also tried it with a java.sql Blob object but it more or less gave the same issues.
Is there something i'm missing?
Look at your UPDATE query closely, the TABLE is not necessary. it should just be like
UPDATE users SET logintoken=? WHERE qrid=?
Refer MySQL Documentation for more information.

oracle collection as function return type

We have a database function to cache sequence values. It accepts a sequence object name and a fetch size, increments the sequence and return the values.
The return type is a oracle collection.
Here is the definition of the db types used by the function:
create or replace type icn_num_type as object(v_inc_num number);
create or replace type icn_num_type_table as table of icn_num_type; --this is returned
The values returned by the function are cached on the application side. We are using ibatis for DAO. All this worked well when the function, types and the sequence objects were all in the same schema.
Now we have the function, types and sequences defined in one parent schema. The user schema has synonyms to the all the above mentioned objects. I am facing the following error now:
--- The error occurred while executing query procedure.
--- Check the {? = call seq_inc(?, ?)}.
--- Check the output parameters (register output parameters failed).
--- Cause: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
ORA-06512: at "SYS.DBMS_PICKLER", line 18
ORA-06512: at "SYS.DBMS_PICKLER", line 58
ORA-06512: at line 1
However when we access the function from SQLDeveloper(user schema) it works fine.
Could some one help me on this issue?
Seems there were issues (restrictions / bugs) with synonyms and Object types back in 9iR2 for java. Google for ORA-21700 and DBMS_PICKLER
I suspect you've got some issue with the JDBC driver being used for iBatis that is resolved for the JDBC version used for SQL Developer.
Grab something like SQuirrel SQL Client and try the JDBC driver you are using for iBatis with that to see if you can reproduce.

Categories

Resources