Problems creating tables for Oracle on H2 in memory DB - oracle

I can't seem to figure out the right combination to get this to work. I have generated DDL from Oracle QL developer with the Quick DDL and the get_ddl functions as well as written my own SQL. All work fine in SQL Plus and SQL Developer, but I can't figure out how to get H2 to accept the SQL.
Ive tried different variations, left off the schema name, etc. Nothing seems to work.
SQL:
CREATE TABLE TEST_SCHEMA.SAVED_SEARCHES(
SEARCHID INT GENERATED ALWAYS AS IDENTITY AUTO_INCREMENT BY 1 START WITH 1 NOT NULL,
NAME VARCHAR2(30) NOT NULL,
USERID VARCHAR2(32 BYTE),
WORKGROUPID VARCHAR2(50 BYTE),
ONECLICK VARCHAR2(1 BYTE) NOT NULL
)
Connection properties:
<Context reloadable="true" crossContext="true">
<Resource
name="jdbc/cts"
auth="Container"
type="javax.sql.DataSource"
removeAbandoned="true"
removeAbandonedTimeout="30"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="test_schema"
password="oracle"
driverClassName="com.test.h2.H2Driver"
url="jdbc:testh2:mem:testdb;MODE=Oracle;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS TEST_SCHEMA\;SET SCHEMA TEST_SCHEMA"
validationQuery="SELECT 1 FROM DUAL"
/>
</Context>
Error:
Syntax error in SQL statement: expected "(, NOT, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, PRIMARY, UNIQUE, NOT, NULL, CHECK, REFERENCES, ,, )"; SQL statement:

Start from studying a syntax of CREATE TABLE statement in H2 database:
http://www.h2database.com/html/grammar.html#create_table
A simplified syntax is:
CREATE TABLE name (
columnDefinition,
columnDefinition,
....
);
where columnDefinition is:
http://www.h2database.com/html/grammar.html#column_definition
columnName dataType [ AUTO_INCREMENT | IDENTITY [ (startInt [,incrementInt ] ) ]]
where elements withins [] brackets are optional
As you see Oracle's syntax:
columnName dataType GENERATED ALWAYS AS IDENTITY AUTO_INCREMENT BY 1 START WITH 1
is completely different than H2's syntax:
columnName dataType IDENTITY (1,1)
You need to rewrite the CREATE TABLE statement by hand to adapt it to H2 database.
Also H2 doesn't alows for VARCHAR2 and (50 BYTE) length
you need to use just VARCHAR( 50 ) or more than 50, see this link:
http://www.h2database.com/html/datatypes.html#varchar_type

Related

How to use keyword VALUE as a field name in H2 database

I inherited a project where in UnitTests an H2 database is being used. On the startup of the project a lot of tables are created and populated with data.
CREATE TABLE SRC_FIELD_VALUE
( ID NUMBER IDENTITY,
INPUT_SRC_FIELD_REF_ID NUMBER,
VALUE VARCHAR2(255),
DESCRIPTION VARCHAR2(255)
);
We recently migrated to the latest version of H2 : 2.1.214
In my POM.XML I added "NON_KEYWORDS=VALUE,ID" to the end of definition but still got an exception :
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "CREATE TABLE SRC_FIELD_VALUE ( ID NUMBER IDENTITY, INPUT_SRC_FIELD_REF_ID NUMBER, [*]VALUE VARCHAR2(255), DESCRIPTION VARCHAR2(255) )"; expected "identifier"; SQL statement:
CREATE TABLE TC_RULE_COMP_DATA ( ID NUMBER IDENTITY, RULE_REF_ID NUMBER, SORT_ORDER NUMBER, VALUE CLOB ) [42001-214]
I also tried to put double quote around "VALUE" but got the same exception. It's interesting that "ID" is not getting considered as KEYWORD though.
What are my options here? I can't rename the fields.

Springboot test fail because of table not found from H2 database, but the table has been created

The problem that I can see is that the table is created with the name 'article' and the query is done with ARTICLE in capital letter. I tried to change the application.properties file to this:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL;NON_KEYWORDS=USER;IGNORECASE=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;DATABASE_TO_LOWER=TRUE
but it doesn't help the problem.
Here is some output from the console that demonstrate the table has been created:
Hibernate: create table "article" ("id" bigint generated by default as identity, "content" clob, "language" integer, "last_edited" timestamp, "published" timestamp, "title" varchar(255), "image_id" bigint, "user_id" bigint not null, primary key ("id"))
and later this pops up:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "ARTICLE" not found; SQL statement: select * from Article where language=? ORDER BY published desc
I tried to name the table in uppercase letter with
DATABASE_TO_LOWER=FALSE, DATABASE_TO_UPPER=TRUE;
and it didn't help either.
What could I try next?

which oracle datatype is mapped to BIGINT?

SQL> CREATE TABLE Product (id NUMBER(19,0) NOT NULL, name VARCHAR2(10 CHAR) NOT NULL);
Table created.
SQL> desc Product;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER(19)
NAME NOT NULL VARCHAR2(10 CHAR)
type NUMBER(19,0) becomes NUMBER(19).
From JDBC, the id type NUMBER(19) is mapped to java.sql.Types.DECIMAL, not java.sql.Types.BIGINT. What is the oracle database type mapped to jdbc BIGINT?
8.3.7 BIGINT
The JDBC type BIGINT represents a 64-bit signed integer value between
-9223372036854775808 and 9223372036854775807.
The corresponding SQL type BIGINT is a nonstandard extension to SQL.
In practice the SQL BIGINT type is not yet currently implemented by
any of the major databases, and we recommend that its use be avoided
in code that is intended to be portable.
The recommended Java mapping for the BIGINT type is as a Java long.
https://docs.oracle.com/javase/1.5.0/docs/guide/jdbc/getstart/mapping.html
However not entirely sure that statement about no RDBMS having implemented BIGINT that way, MS SQL Server documentation states:
Data type Range Storage
bigint -2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807) 8 Bytes
https://learn.microsoft.com/en-us/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql
Notwithstanding the JDBC mapping is to LONG

H2 Schema initialization. Syntax error in SQL statement

I have a spring boot application and I trying to initialize some data on application startup.
This is my application properties:
#Database connection
spring.datasource.url=jdbc:h2:mem:test_db
spring.datasource.username=...
spring.datasource.password=...
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.initialize=true
spring.datasource.schema=schema.sql
spring.datasource.data=schema.sql
#Hibernate configuration
#spring.jpa.hibernate.ddl-auto = none
This is schema.sql:
CREATE TABLE IF NOT EXISTS `Person` (
`id` INTEGER PRIMARY KEY AUTO_INCREMENT,
`first_name` VARCHAR(50) NOT NULL,
`age` INTEGER NOT NULL,
PRIMARY KEY(`id`)
);
and data.sql
INSERT INTO `Person` (
`id`,
`first_name`,
`age`
) VALUES (
1,
'John',
20
);
But I got 'Syntax error in SQL statement' on application startup:
19:08:45.642 6474 [main] INFO o.h.tool.hbm2ddl.SchemaExport - HHH000476: Executing import script '/import.sql'
19:08:45.643 6475 [main] ERROR o.h.tool.hbm2ddl.SchemaExport - HHH000388: Unsuccessful: CREATE TABLE Person (
19:08:45.643 6475 [main] ERROR o.h.tool.hbm2ddl.SchemaExport - Syntax error in SQL statement "CREATE TABLE PERSON ( [*]"; expected "identifier"
Syntax error in SQL statement "CREATE TABLE PERSON ( [*]"; expected "identifier"; SQL statement:
I can't understand, what's wrong with this SQL.
Try this code. Remove PRIMARY KEY(id) and execute it.
CREATE TABLE IF NOT EXISTS `Person` (
`id` INTEGER PRIMARY KEY AUTO_INCREMENT,
`first_name` VARCHAR(50) NOT NULL,
`age` INTEGER NOT NULL
);
This error results from the structure of the CREATE TABLE declaration.
It will be the result when you have an extra comma in the end of your SQL declaration--no column declaration following the comma. For example:
CREATE TABLE IF NOT EXISTS `Person` (
`id` INTEGER PRIMARY KEY AUTO_INCREMENT,
`first_name` VARCHAR(50) NOT NULL,
`age` INTEGER NOT NULL, --note this line has a comma in the end
);
That's because CREATE TABLE expects a list of the columns that will be created along with the table, and the first parameter of the column is the identifier. As you check here, the column declaration follows the structure:
identifier datatype <constraints> <autoincrement> <functions>
Thus, in your case, as #budthapa and #Vishwanath Mataphati have mentioned, you could simply remove the PRIMARY KEY(id) line from the CREATE TABLE declaration. Moreover, you have already stated that id is a primary key on the first line of the column definitions.
In case you do not have a statement as the PRIMARY KEY declaration, be sure to check for the extra comma following your last column declaration.
Try this, as you have used Table_name
CREATE TABLE IF NOT EXISTS Person (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50) NOT NULL,
age INTEGER NOT NULL
);
I was add below in to application.properties and it work for me
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring.jpa.properties.hibernate.globally_quoted_identifiers_skip_column_definitions = true
What helped in my case was removing single quotes from the table name in my insert query
I had to change this:
INSERT INTO 'translator' (name, email) VALUES ('John Smith', 'john#mail.com');
to this:
INSERT INTO translator (name, email) VALUES ('John Smith', 'john#mail.com');
You set auto increment id, so you can't insert new record with id.
Try INSERT INTO `Person` (
`first_name`,
`age`
) VALUES (
'John',
20
);
I ran into same issue. I fixed that with these application.properties:
spring.jpa.properties.hibernate.connection.charSet=UTF-8
spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
Some issue with multi-line and default encoding.

Create POSTGRES table with VARCHAR[] in H2 in-memory database

I have DDL for my PostgreSQL database. One of the columns in the table is of type VARCHAR[]. H2 fails to create this table, even if the database is running in PosgtreSQL compatibility mode (url: jdbc:h2:mem:user-management;MODE=PostgreSQL)
Simplified DDL:
create table "users" (
"uuid" VARCHAR NOT NULL PRIMARY KEY,
"roles" VARCHAR[] NOT NULL
);
Is there any data type that is compatible between H2 and PostgreSQL and is actually a varchar array? Thanks!
It is possible to use array here, it's worked for me in h2 postgre mode.
create table "users" (
"uuid" VARCHAR NOT NULL PRIMARY KEY,
"roles" varchar array
);

Resources