简体   繁体   中英

query from multiple databases using in-memory database

How to write below inner join query using in-memory database such as H2 db.

select * from emp e inner join other_db.dept d on e.id=d.eid

emp table is created in db1 database and dept table is created in other_db database.

Problem with in-memory db is that database name is not associated with data-source. So, we cannot use other_db.dept in the query.

As suggested by Thomas Mueller, please find below code written in Java and Spring framework with LINKED TABLE

Spring configuration file:

<jdbc:embedded-database id="db1DataSource" type="H2">
    <jdbc:script location="classpath:schema-db1.sql" />
</jdbc:embedded-database>

<jdbc:embedded-database id="otherdbDataSource" type="H2">
    <jdbc:script location="classpath:schema-other.sql" />
</jdbc:embedded-database>

schema-db1.sql

SET MODE MSSQLServer

CREATE TABLE emp ( id int NOT NULL, name varchar(30) NOT NULL)

CREATE LINKED TABLE other_db ('org.h2.Driver', 'jdbc:h2:mem:test', 'sa', '', 'dept')

schema-other.sql

SET MODE MSSQLServer

CREATE TABLE dept ( id int NOT NULL, name varchar(20) NOT NULL, eid int NOT NULL)

Now, can I write below query:

select * from emp e inner join other_db.dept d on e.id=d.eid

Infact, I am getting below exception on running the code:

Table dept not found

H2 supports Linked Tables to access tables in another database. If you create a linked table first, you can then use it as you did in the query in your question. It doesn't matter if the source and / or target database is in-memory or not.

The table name is case sensitive in the same way as database metadata identifiers, so if you create a table like this in H2: CREATE TABLE dept , then the linked table needs to be uppercase:

CREATE LINKED TABLE other_db
('org.h2.Driver', 'jdbc:h2:mem:test', 'sa', '', 'DEPT')

I created two schemas under same database, using INIT property in the h2 url as shown below:

<bean class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" id="db1DataSource">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:test;INIT=CREATE SCHEMA IF NOT EXISTS first_db\;SET SCHEMA first_db" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<jdbc:initialize-database data-source="db1DataSource">
    <jdbc:script location="classpath:schema-db1.sql" />
</jdbc:initialize-database>

<bean class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" id="otherdbDataSource">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:test;INIT=CREATE SCHEMA IF NOT EXISTS other_db\;SET SCHEMA other_db" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<jdbc:initialize-database data-source="otherdbDataSource">
    <jdbc:script location="classpath:schema-other.sql" />
</jdbc:initialize-database>

Now, able to run below qyery:

select * from emp e inner join other_db.dept d on e.id=d.eid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM