Migrate data from old MySQL database - java

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

Related

Automate partition creation in databases

Is there a way to create partitions from Java spring code, in case any database is missing partition?
In the DB we write query like this -
ALTER TABLE <table_name> ADD PARTITION (PARTITION p1 VALUES LESS THAN (time));
You can fire any random SQL query in spring application using jdbcTemplate object.
jdbcTemplate.execute("DROP TABLE customers IF EXISTS");

Doing an INSERT ALL using JDBC in ORACLE

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

Sybase DataContext : The column prefix does not match with a table name or alias name

We are dealing with sybase database in core java code. We are using org.eobjects.metamodel.DataContext to parse query.
String sCol[]=table.getColumnNames();
Query query=dataContext.query().from(table.getName()).select(sCol).toQuery();
return new QueryIterator(dataContext.executeQuery(query).iterator());
But it executing query. Same code working fine with Oracle database to parse and execute query.
Some of query example generated are :
select City.CityName from ownername.City
select City.CityName from City
select CityName from ownername.City
select CityName from City
select ownername.City.CityName from ownername.City
SELECT "City"."CityName" FROM ownername."City"
select * from ownername.City
No any of above query executed. We are getting these errors :
Not capable of parsing FROM token: "ownername"."City"
Could not execute query: The column prefix '"City"' does not match with a table name or alias name used in the query. Either the table is not specified in the FROM clause or it has a correlation name which must be used instead.
Not capable of parsing SELECT token: ownername.City.CityName
How can we execute query using metamodel wih SYBASE database OR is there any other way to execute sybase queries?
Oracle (and Microsoft) use a schema logical construct that Sybase ASE does not. In SAP/Sybase ASE, all tables and columns in a database are in the same schema. It is possible to users to have their own objects in the database though, so there is the possibility of imitating some of the schema behavior using user ownership, but it would require an extra level of effort.
For Sybase the proper query syntax would be:
SELECT [ Col1, Col2 | * ]
FROM [dbName].[ownerName.]TABLE
In your case
SELECT CityName
FROM dbName.ownername.City
In Sybase ASE, it's typically best practice to have all objects owned by 'dbo', so in that case you can omit the owner from the query:
SELECT CityName
FROM dbName..City
Full query syntax and information can be found in the Query Section of the Transact SQL Users Guide in the documentation.
The error messages you're getting are coming from MetaModel's query parser layer. It is searching for matching column and table names in the metadata of your database before it's even firing the query.
I notice that you're using namespace "org.eobjects.metamodel". You should upgrade to Apache MetaModel ("org.apache.metamodel") if possible since a lot has been improved in MetaModel since it's introduction into Apache. Including a lot of query parser improvements.

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

how to execute the stored procedure in hibernate 3

I am new in hibernate. I am using hibernate 3 in my application using hibernate annotations , I am developing application in struts 1.3.
My question is :
I have googled a lot but could not understand how to call a stored procedure in hibernate using annotations , I have a simple scenario : suppose I have 2 fields in my jsp say 1) code 2) name , I have created a stored procedure in database for inserting those records into table. Now my problem is that how to execute it
List<MyBean> list = sessionFactory.getCurrentSession()
.getNamedQuery("mySp")
.setParameter("code", code)
.setParameter("name", name)
I don't know the exact code how to do this. But I guess something like that actually I come from jdbc background therefore have no idea how to do this and same thing I want when selecting the data from database using stored procedure.
Hibernate provides many simple ways to call a SP like
Native SQL
Named Query in native SQL as Annotation/XML mapping file
Following link shows how each of above can be implemented
http://www.mkyong.com/hibernate/how-to-call-store-procedure-in-hibernate/
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html#sp_query
Sample to run native SQL query using hibernate:
Session session = getSession();
SQLQuery sqlQuery = session.createSQLQuery("SELECT COUNT(id) FROM tableName WHERE external_id = :external_id");
sqlQuery.setParameter("external_id", idValue);
int count = ((BigInteger) sqlQuery.uniqueResult()).intValue();
releaseSession(session);
You can execute your stored procedure using Hibernate's SQLQuery with the same SQL as when you call it against the database. For example, in postgreSQL:
String query = "select schema.procedure_name(:param1)";
SQLQuery sqlquery = sessionFactory.getCurrentSession().createSQLQuery(query);
sqlquery.setInteger("param1", "this is first parameter");
sqlQuery.list();
Hope it helps.

Categories

Resources