H2 SQL database - INSERT if the record does not exist
The following works for MySQL, PostgreSQL, and the H2 database:
drop table ACCESSLEVELS;
create table ACCESSLEVELS(id int, name varchar(255));
insert into ACCESSLEVELS select * from (
select 0, 'admin' union
select 1, 'SEO' union
select 2, 'sales director' union
select 3, 'manager' union
select 4, 'REP'
) x where not exists(select * from ACCESSLEVELS);
Insert into h2 table if not exists
The merge statement should allow you to achieve what you want. I'm no expert on H2, but I've used the MERGE
statement in SQL Server several times and from the looks of that website it should do the trick.
From the website:
Updates existing rows, and insert rows that don't exist. If no key column is specified, the primary key columns are used to find the row.
H2 database content is not persisting on insert and update
But the getAllRequest() assert fails as the output still contains the single row(as inserted by schemadata.sql) => which means the insertRequest change is not persisted
I would double-check that the assert(Await.result(response2, 5 seconds).size === 2)
line is failing because of a size difference. Could it be failing for some other general failure?
For example, as INIT
is run on each connection it could be that you are re-creating the database for each connection. Unless you're careful with the SQL, that could produce an error such as "table already exists". Adding TRACE_LEVEL_SYSTEM_OUT=2;
to your H2 URL can be helpful in tracking what H2 is doing.
A couple of suggestions.
First, you could ensure your SQL only runs as needed. For example, your schema.sql
could add checks to avoid trying to create the table twice:
CREATE TABLE IF NOT EXISTS my_table( my_column VARCHAR NULL );
And likewise for your schemadata.sql
:
MERGE INTO my_table KEY(my_column) VALUES ('a') ;
Alternatively, you could establish schema and test data around your tests (e.g., possibly in Scala code, using Slick). Your test framework probably has a way to ensure something is run before and after a test or test suit.
Slick insert into H2, but no data inserted
My assumptions are that your JDBC url is something like jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'init.sql'
and no connection pooling is used.
There are two scenarios:
- the connection is performed with
keepAliveConnection = true
(or by appendingDB_CLOSE_DELAY=-1
to the JDBC url) and theinit.sql
is something like:
DROP TABLE IF EXISTS QUESTION;
CREATE TABLE QUESTION(...);
INSERT INTO QUESTION VALUES(null, ...);
INSERT INTO QUESTION VALUES(null, ...);
- the connection is performed with
keepAliveConnection = false
(default) (without appendingDB_CLOSE_DELAY=-1
to the JDBC url) and theinit.sql
is something like:
CREATE TABLE QUESTION(...);
INSERT INTO QUESTION VALUES(null, ...);
INSERT INTO QUESTION VALUES(null, ...);
The call to questionDao.createQuestion
will open a new connection to your H2 database and will trigger the initialization script (init.sql
).
In both scenarios, right after this call, the database contains a QUESTION
table with 2 rows.
In scenario (2) after this call the connection is closed and according to H2 documentation:
By default, closing the last connection to a database closes the database. For an in-memory database, this means the content is lost. To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database URL. To keep the content of an in-memory database as long as the virtual machine is alive, use jdbc:h2:mem:test;DB_CLOSE_DELAY=-1.
The call to questionDao.questions
will then open a new connection to your H2 database and will trigger again the initialization script (init.sql
).
In scenario (1) the first connection is kept alive (and also the database content) but the new connection will re-execute the initialization script (init.sql
) erasing the database content.
Given that (in both scenarios) questionDao.createQuestion
returns 3
, as expected, but then the content is lost and so the subsequent call to questionDao.questions
will use a freshly initialized database.
INSERT INTO table SELECT not working with constant values in H2 DB
As mentioned in the comments,
- Use single quotes for sting constants.
- Do not use braces with constants in select clause.
- Check the join condition. Without matching 2 tables based on common column, you are doing a Cartesian product
Related Topics
Query Featuring Outer Joins Behaves Differently in Oracle 12C
Powershell SQL Select Output to Variable
What Is the Equivalent of Regexp_Substr in MySQL
A Reliable Way to Verify T-SQL Stored Procedures
Use Google Bigquery to Build Histogram Graph
#1222 - the Used Select Statements Have a Different Number of Columns
Create Unqiue Case-Insensitive Constraint on Two Varchar Fields
SQL Query to Count() Multiple Tables
How to Calculate Running Multiplication
What Would Be the Best Way to Store Records Order in SQL
Ssrs - Keep a Table the Same Width When Hiding Columns Dynamically
Reason for System.Transactions.Transactionindoubtexception
Unsupported Subquery Expression:Correlating Expression Cannot Contain Unqualified Column References
Ms SQL Server: Check to See If a User Can Execute a Stored Procedure
Efficiently Include Column Not in Group by of SQL Query
Rounding Issue in Log and Exp Functions
Generate SQL Temp Table of Sequential Dates to Left Outer Join To