Create table if not exists in DB2 - java

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.

Related

SymmetricDS length for type varchar cannot exceed N

so I'm trying to use symmetricDS for replicating java h2 database to postgres. I'm using the zip file simple configuration. Here is what happen. I followed the getting started guide, download the symmetricds, and try the demo, then I tried with my own configuration with some table in the trigger. But:
If I replicate the table without varchar field in h2 it works perfectly fine.
If I have a table that has varchar field in it, it crash during creating the table.
JdbcSqlTemplate - ERROR: length for type varchar cannot exceed 10485760
Position: 161. Failed to execute: CREATE TABLE "asset"(
"db_id" BIGINT NOT NULL DEFAULT nextval('"asset_db_id_seq"'),
"id" BIGINT NOT NULL,
"account_id" BIGINT NOT NULL,
"name" VARCHAR(2147483647) NOT NULL,
"description" VARCHAR(2147483647),
"quantity" BIGINT NOT NULL,
"decimals" SMALLINT NOT NULL,
"initial_quantity" BIGINT NOT NULL,
"height" INTEGER NOT NULL,
"latest" BOOLEAN DEFAULT 'TRUE' NOT NULL,
PRIMARY KEY ("db_id")
)
indeed a clear error saying the varchar should not exceed 255, but that's how the source database is, is there anyway to force any varchar to TEXT type? or are there any other way around this? or is this a bug in symmetricds has yet to be solved?
Thanks.
I managed to go way around this by creating the table on target database manually. Here is what I did before running bin/sym.
generate query for table I want to create using dbexport by bin/dbexport --engine corp-000 --compatible=postgres --no-data table_a table_b > samples/create_asset_and_trade.sql
modify the flaw in generated query file samples/create_asset_and_trade.sql. in my case it's the length of the varchar.
after fixing that, run the generated query to fill in the target database using dbimport. bin/dbimport --engine store-001 samples/create_asset_and_trade.sql.
running bin/sym should be okay now, it'll detect that the table is already created, and skip the table creation step.
This is not the ideal way, but it should work for now.

H2 database throwing an unexpected JdbcSQLException on CREATE SEQUENCE

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.

Can't create table in DB2

I can't create the table in DB2 via Eclipse. I've been stuck for a long time and I've searched a lot for the following error:
Error SQLCODE=-204
Below is my code:
CREATE TABLE BaseEntity(
wts Timestamp NOT NULL,
siteID NOT NULL,
oid varchar2(11),
PRIMARY KEY (oid),
AccelerationVector varchar2(8),
DeadReckoningAlgorithm varchar2(8),
Orientation varchar2(8),
WorldLocation varchar2(8),
VelocityVector varchar2(8)
)
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=NOT, DRIVER=3.63.123
at com.ibm.db2.jcc.am.fd.a(fd.java:679)
at com.ibm.db2.jcc.am.fd.a(fd.java:60)
at com.ibm.db2.jcc.am.fd.a(fd.java:127)
at com.ibm.db2.jcc.am.ho.b(ho.java:2317)
at com.ibm.db2.jcc.am.ho.c(ho.java:2300)
at com.ibm.db2.jcc.t4.cb.l(cb.java:370)
at com.ibm.db2.jcc.t4.cb.a(cb.java:62)
at com.ibm.db2.jcc.t4.q.a(q.java:50)
at com.ibm.db2.jcc.t4.tb.b(tb.java:220)
at com.ibm.db2.jcc.am.io.lc(io.java:3318)
at com.ibm.db2.jcc.am.io.b(io.java:4275)
at com.ibm.db2.jcc.am.io.dc(io.java:759)
at com.ibm.db2.jcc.am.io.executeUpdate(io.java:742)
at testDB.XmlToDBSchema.insertIntoDB(XmlToDBSchema.java:37)
at testDB.XmlToDBSchema.createDBSchma(XmlToDBSchema.java:191)
at testXMLPar.testXML.main(testXML.java:16)
The error -204 refers to an undefined name which can have several reasons. See here for an overview. In your case the statement has several issues:
siteID does not have a type,
primary key is in the middle of the statement, this should be moved to the end
varchar2 can only be used if the database has been enabled for it, else you may get this error messages
To correct the errors you have to rewrite the statement, use data types where needed and to make sure that varchar2 support is enabled (check get db cfg).

Can I SELECT with LAST_INSERT_ID() after INSERT Batch without any cares?

I'm asking myself if it is possible to SELECT with LAST_INSERT_ID() in WHERE Clause after an batch of INSERTs without getting corrupt data in the tables? I'm thinking of the scenario that multiple users doing the same stuff at the same time. I develop an JSF Application in which this scenario can be possible.
In hard Code my SELECT after INSERTs looks like this:
preparedstatement.addBatch(
"INSERT INTO table1(all the FIELDS)"
+ "VALUES(null, ...);"
);
preparedstatement.addBatch(
"INSERT INTO table2(all the FIELDS)"
+ "VALUES(null, LAST_INSERT_ID(), ...);"
);
preparedstatement = connect.prepareStatement(
"SELECT id FROM table3 WHERE id = LAST_INSERT_ID();"
);
preparedstatement.executeBatch();
resultSet = preparedstatement.executeQuery();
Get I problems with this implementation or is there an better way?
Best Regards
You should be fine, quoting MySQL's documentation:
The ID that was generated is maintained in the server on a
per-connection basis. This means that the value returned by the
function to a given client is the first AUTO_INCREMENT value generated
for most recent statement affecting an AUTO_INCREMENT column by that
client. This value cannot be affected by other clients, even if they
generate AUTO_INCREMENT values of their own. This behavior ensures
that each client can retrieve its own ID without concern for the
activity of other clients, and without the need for locks or
transactions.
MySQL Last_insert_id

Auto generate key on JDBC insert in SQL Server

Is there a general, cross RDMS, way I can have a key auto generated on a JDBC insert? For example if I have a table with a primary key, id, and an int value:
create table test (
id int not null,
myNum int null
)
and do an insert
PreparedStatement statement = connection.prepareStatement("insert into test(myNum) values(?)", Statement.RETURN_GENERATED_KEYS);
statement.setInt(1, 555);
statement.executeUpdate();
statement.close();
I get an java.sql.SQLException: Cannot insert the value NULL into column 'id'.
I have a feeling this is entirely RDMS dependent. We are using using SQL Server 2005 and I have set
CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 1) ON [PRIMARY]
in the table with no luck.
This is completely database dependent. There are two main options: 1 - DBMSs that allow an auto-increment keyword next to the primary key definition and 2 - DBMSs that provide sequence generators (that you then can use to generate the new values for the PK, for instance by writing a "before insert" trigger that automatically inserts the new value in the column before completing the insertion ).
As far as I know:
Firebird uses sequences
DB2 allows to define a column as "GENERATED BY
DEFAULT AS IDENTITY";
Interbase uses sequences (called generators)
MySQL has the "AUTO_INCREMENT" clause
Oracle uses sequences
PostgreSQL uses sequences
SQLServer has the "IDENTITY(1,1)" clause
You need to set the id column in the test table to autocreate an identity. In the case of SQL Server, you need to set the IDENTITY() property on the ID column.
This is database dependant. Oracle requires a SEQUENCE to be created and on MySQL you just set the column as auto increment.
You could always use Hibernate.
As far as I know it's database dependent. Likewise with inserting timestamps; some will insert the current time when you insert a null.

Categories

Resources