Doing an INSERT ALL using JDBC in ORACLE - java

I am using Oracle Database 12c Enterprise Edition
I want to insert records into 2 tables say TABLE1 and TABLE2 back to back using JDBC. These 2 tables have a primary key and foreign key relationship based on a common column say ID_COLUMN
I am planing to use the following single query and fire it via my Java application via JDBC:
insert all
into TABLE1 (ID_COLUMN,COL2,COL3,COL4,COL5,COL6) values(?,?,?,?,?,?)
into TABLE2 (COL1_1,COL_1_2,COL_1_3,ID_COLUMN) values('blah',42,'rubbish',
select test_ctrl.seq_test_id.nextval FROM dual)
select * from dual;
My basic requirement is that I need to INSERT TABLE2 with the latest ID_COLUMN from TABLE1 from my current session.
I know the usage of select test_ctrl.seq_test_id.nextval FROM dual in the INSERT ALL statement is not correct. But it being Oracle I cant use SCOPE_IDENTITY()
Please suggest how can I make this query work

"But it being Oracle I cant use SCOPE_IDENTITY()"
Ah but you can. In Oracle 12c they introduced identity columns: these are a special variant of virtual columns.
create table my_table (
id number generated always as identity
....
, constraint my_table_pk primary key (id)
Find out more.

I seem to have found out the answer to my question.Modified the query like this.Please take note of edme_ctrl.seq_ts_annotation_id.nextval and edme_ctrl.seq_ts_annotation_id.currval
INSERT ALL INTO "SPI7CG_CgNvI".X$ANNOTATIONS(ANNOTATION_ID,CATEGORY,REASON,COMMENTS,AUTHOR,ADJUSTMENT_TYPE,ADJUSTMENT_VALUE) VALUES (edme_ctrl.seq_ts_annotation_id.nextval, '51','33','Test Bulk Insert','kshiam','A',10) INTO "SPI7CG_CgNvI".X$DATA_ANNOTATIONS(ANNOTATION_ID, TABLE_NAME, TABLE_ROW_ID,COLUMN_NAME) VALUES (edme_ctrl.seq_ts_annotation_id.currval,'W$XXXXXGNVBSNSSNDCTRSSR007',164921155,'IVXXXXXGNVBXWGSQDTWQRTR0003') select * from dual

Related

Merge and When Matched query giving an error sql server

I have a query which I am trying to test. The query should update the data if it finds data in the table with existing primary key. If it doesn't then insert into the table.
The Primary key is of type int and in the properties I can see Identity is set to "True" which I assume it means that it will automatically set the new id for the primary if it is inserted.
MERGE INTO Test_table t
USING (SELECT 461232 ID,'Test1-data' Fascia FROM Test_table) s
ON (t.ID = s.ID)
WHEN MATCHED THEN
UPDATE SET t.Fascia = s.Fascia
WHEN NOT MATCHED THEN
INSERT (Fascia)
VALUES (s.Fascia);
The issue here is this query doesn't work and it never inserts the data or updates. Also, query gets compiled and I don't get any compilation error
Also the reason I want this query is to work because then I will use Java prepared statement to query the database so I am assuming I can do
SELECT ? ID,? Fascia FROM Test_table
So that I can pass the values with set methods in java.
Please let me know if there is something wrong in my query.
You are selecting from the target table as your source.
You either need to remove your FROM Test_table or have at least 1 row in Test_table prior to your merge.
rextester demo: http://rextester.com/XROJD28508
MERGE INTO Test_table t
USING (SELECT 461232 ID,'Test1-data' Fascia --FROM Test_table
) s
ON (t.ID = s.ID)
WHEN MATCHED THEN
UPDATE SET t.Fascia = s.Fascia
WHEN NOT MATCHED THEN
INSERT (Fascia)
VALUES (s.Fascia);

jOOQ and bridge tables

I'm trying to imagine how to use jOOQ with bridge tables.
Suppose you have
CREATE TABLE TableA (
id BIGSERIAL PRIMARY KEY
)
CREATE TABLE TableB (
id BIGSERIAL PRIMARY KEY
)
CREATE TABLE TableBridge (
id BIGSERIAL,
table_a_id INTEGER NOT NULL,
table_b_id INTEGER NOT NULL,
CONSTRAINT tablea_pk_id PRIMARY KEY (table_a_id)
REFERENCES TableA (id) MATCH SIMPLE,
CONSTRAINT tableb_pk_id PRIMARY KEY (table_b_id)
REFERENCES TableB (id) MATCH SIMPLE
)
When mapping this schema using jOOQ there will be three record classes, TableARecord, TableBRecord and TableBridgeRecord.
If I want to persist through an insert a record for TableA, should I simply first create and persist the TableB records, then persit rows for TableB and then manually add the TableBridge rows? Isn't there any way to automatically save also the rows in the bridge table?
There are several ways to solve this kind of problem:
1. Do it with a "single" jOOQ statement (running three SQL statements)
The most idiomatic way to solve this kind of problem with standard jOOQ would be to write a single SQL statement that takes care of all three insertions in one go:
ctx.insertInto(TABLE_BRIDGE)
.columns(TABLE_BRIDGE.TABLE_A_ID, TABLE_BRIDGE.TABLE_B_ID)
.values(
ctx.insertInto(TABLE_A)
.columns(TABLE_A.VAL)
.values(aVal)
.returning(TABLE_A.ID)
.fetchOne()
.get(TABLE_A.ID),
ctx.insertInto(TABLE_B)
.columns(TABLE_B.VAL)
.values(bVal)
.returning(TABLE_B.ID)
.fetchOne()
.get(TABLE_B.ID)
)
.execute();
The above works with jOOQ 3.8. Quite possibly, future versions will remove some of the verbosity around returning() .. fetchOne() .. get().
2. Do it with a single SQL statement
I assume you're using PostgreSQL from your BIGSERIAL data type usage, so the following SQL statement might be an option to you as well:
WITH
new_a(id) AS (INSERT INTO table_a (val) VALUES (:aVal) RETURNING id),
new_b(id) AS (INSERT INTO table_b (val) VALUES (:bVal) RETURNING id)
INSERT INTO table_bridge (table_a_id, table_b_id)
SELECT new_a.id, new_b.id
FROM new_a, new_b
The above query is currently not supported entirely via jOOQ 3.8 API, but you can work around the jOOQ API's limitations by using some plain SQL:
ctx.execute(
"WITH "
+ " new_a(id) AS ({0}), "
+ " new_b(id) AS ({1}) "
+ "{2}",
// {0}
insertInto(TABLE_A)
.columns(TABLE_A.VAL)
.values(aVal)
.returning(TABLE_A.ID),
// {1}
insertInto(TABLE_B)
.columns(TABLE_B.VAL)
.values(bVal)
.returning(TABLE_B.ID),
// {2}
insertInto(TABLE_BRIDGE)
.columns(TABLE_BRIDGE.TABLE_A_ID, TABLE_BRIDGE.TABLE_B_ID)
.select(
select(field("new_a.id", Long.class), field("new_b.id", Long.class))
.from("new_a, new_b")
)
);
Clearly also here, there will be improvements in future jOOQ APIs.
3. Do it with UpdatableRecords
In this particular simple case, you could get away simply by calling:
TableARecord a = ctx.newRecord(TABLE_A);
a.setVal(aVal);
a.store();
TableBRecord b = ctx.newRecord(TABLE_B);
b.setVal(bVal);
b.store();
TableBridgeRecord bridge = ctx.newRecord(TABLE_BRIDGE);
bridge.setTableAId(a.getId());
bridge.setTableBId(b.getId());
bridge.store();

How to update 2 tables using one query in JPA native query?

I have 2 tables TABLE1 and TABLE2.Table1 is having name and Table2 is having email and Phone.
To get the name,email and phone,I query as below
query = entityManagerUtil.createNativeQuery("select s.Name,c.Phone1,c.Email1 from Table1 s,Table2 c where c.id= s.NodeID and s.NodeID =21")
Now my next requirement is to update name,email and phone.As these parameters are present in different tables so I am searching for single query which will update 2 tables.Unfortunately I am using sql server and there is no way to update 2 tables using single query
So I am thinking to use #Transactional and 2 queries to update 2 tables like the follow
#Transactional
public void updateDetails()
{
Query query1= entityManagerUtil.entityManager.createNativeQuery("update Table1 set Name='' where id in (select NodeID from Table 2) and NodeID=21");
Query query2= entityManagerUtil.entityManager.createNativeQuery("update Table2 set Email='' and phone1='' where NodeID in (select id from Table 2) and NodeID=21");
query1.executeUpdate();
query2.executeUpdate();
}
Is there any other better way to update 2 tables?
you can use JDBCTemplate
http://sujitpal.blogspot.com.es/2007/03/spring-jdbctemplate-and-transactions.html
It allows to do multiple queries with one connection, so you save some time instead of doing it twice.
Why don't you use Hibernate entities for that. Just load the entities associated with Table1 and table2, modify them and let the automatic dirty checking mechanism to update the tables on your behalf. That's one reason for using an ORM by the way.

Apache Derby: Achieving 'SELECT INTO' behaviour

It is possible in MS SQL Server to store the results of query into a table, and most importantly, have the query create the table:
SELECT an_existing_column
INTO table_xyz
FROM an_existing_table
This is also possible in MySQL using:
CREATE TABLE table_xyz
SELECT an_existing_column
FROM an_existing_table
I have searched the Apache Derby Reference Guide and cannot see a method for achieving similar behaviour.
Does anyone know if this possible in Apache Derby?
Store the results of a query into a table:
INSERT INTO table_xyz (an_existing_column) SELECT an_existing_column FROM an_existing_table;
Create a table from another table:
All Columns:
CREATE TABLE table_xyz AS SELECT * FROM an_existing_table WITH NO DATA;
Specific Column:
CREATE TABLE table_xyz AS SELECT an_existing_column FROM an_existing_table WITH NO DATA;
It does not work in JAVA DB, the correct way to do it is:
For all columns:
Step 1: Create a new table with a different name. for example, my_new_table:
CREATE TABLE my_new_table AS SELECT * FROM original_table WITH NO DATA;
This statement creates a new table from original table in the same format and no data copied. It is required to specify WITH NO DATA for it creates a new table with the same columns.
Step 2: Copy data from orig_table to my_new_table using INSERT INTO.
INSERT INTO my_new_table SELECT * FROM orig_table.
Then you will have all the data copied.

Migrate data from old MySQL database

I recently rewrote a Java EE web application (running on a MySQL database) to Rails 3.1. The problem now is that the database model of the new application is not the same as the old one because I added, removed and renamed some attributes. The database table names are also different.
Is there a way of migrating this data? The only way I can imagine to do this is writing a stored procedure with many ALTER TABLE and CREATE TABLE statements to update the database to the new model.
Thanks in advanced.
Solution:
I finally used INSERT..SELECT statements in a mysql stored procedure to migrate the data. INSERT INTO new_schema.new_table SELECT FROM old_schema.old_table. I am now considering making a Rake task to call that procedure and doing other stuff.
The only way is to write a script that take the data from the old db and insert thme in the new db. Or you can in some way to connect to the two databases and then make some select and insert query, something like
insert into new_db.table as select old_db.table.field1, ....
or
insert into new_db.table (field_1, field_2) values (select old_db.table.field_1, ...)
In any way, is a manual process, also if can be automated to some extend with a script
Instead of a Store procedure you can try with rails and some sql within the rails console using the information_schema of mysql
sql = ActiveRecord::Base.connection()
old_tables = sql.execute "select table_name from information_schema.tables where table_schema = your_old_schema"
res.each do | old_table|
old_fields = sql.execute "select distinct column_name, data_type from information_schema.columns where table_name='#{old_table}' and table_schema='your_old_schema'"
new_fields = sql.execute "select distinct column_name, data_type from information_schema.columns where table_name='#{old_table}' and table_schema='your_new_schema'"
#compare fields and so on...
end

Categories

Resources