How to use COPY table command of Oracle DBMS using JDBC? - java

I'm trying copy table from one database to another(On different machines), and using JDBC Template to execute query, but this request is specific to Oracle:
COPY FROM username1/passwd1#//192.168.3.17:1521/PROD_SERVICE to username2/passwd2#//192.168.4.17:1521/SANDBOX_SERVICE INSERT TABLE_C (*) USING (SELECT * FROM TABLE_C);
And I get error:
Caused by: java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
How can I use specific to Oracle syntax in JDBC?

Like some of the comments have already clarified, COPY is a sqlplus command, and it has been deprecated for a while. You cannot use it inside JAVA, because this command is not part of the SQL engine, it's just a kind of additional feature available only in sqlplus. It is still available, but only for backwards compatibility.
If you want to copy a table using Java, you need to understand first some things:
Java, or any external engine for that matter, can't connect at the same time to both databases. Either it connects to one or to the other.
You need to have a kind of bridge between both databases, so that your Java program is only acting as trigger.
Copying tables between databases is something related to the database, so you should think in using tools provided by your database engine. You have some options, like Datapump or RMAN, although I consider Datapump the best suitable for your scenario.
However, if you insist in using Java, first you need to have a database link between both databases. Then you can use Java to invoke an insert from one database to another.
https://docs.oracle.com/database/121/SQLRF/statements_5006.htm#SQLRF01205
If you don't want to depend on thsnames entries in the server, here an example of database links:
CREATE DATABASE LINK to_my_remote_user
CONNECT TO remote_user IDENTIFIED BY password
USING '(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=remote_server)(PORT=remote_port))
(CONNECT_DATA=(SERVICE_NAME=remote_service_name))
)';
Once you have the dblink created, then you can connect from java to the database where the link is available and copy the data to the remote database
INSERT INTO remote_user.remote_table#to_my_remote_user
select * from local_user.local_table ;
Important: Normally dblinks are not allowed on Production systems, because they increase security risks. Also remember that DDL operations over a database link require an extra step, such as using the procedure DBMS_UTILITY.EXEC_DDL_STATEMENT#dblink('create table ...);
Another option outside of Java is using SQL Developer copy feature. Although I only recommend it for small tables. If you want to use it with big tables, it will probably hang. You can read here an good example :
copy from one database to another using oracle sql developer - connection failed

Related

How to simulate an Oracle DB link in H2 database?

My problem is the following: I have to test an application which is written in Java Spring.
In real life the DB server will be an Oracle. There are some select where a DB link is used.
(For example: select * from country#isem_db; )
In test environment we use H2 database which doesn't know this syntax.(#)
My question is : Is this somehow possible to make this Oracle syntax acceptable for H2 ? Is some workaround exists for it without modifying the original source code?
Your Oracle code should not contain embedded database links. Database link names may change across environments, which makes your code brittle. Or you may need to switch to using a local copy (or materialized view).
The correct approach is to use synonyms. In Oracle you would create a synonym for the remote table:
create synonym isem_country for country#isem_db;
Obviously you need to change your Oracle code to reference the synonym name instead of the remote table.
This gives you the solution for running in H2, providing you're using a recent version which supports table synonyms. In H2 you would create a synonym with the same name but on the local table:
create synonym isem_country for country;

Netezza connection wtih C++

I am developing an application and i need to migrate data from netezza database into another database. For that i need to write an application in C++ or java to read from netezza database. Can anyone guide if there are any native API available for C++ or do we have to use ODBC. If ODBC is the way to go can anyone guide me how.
I don't think there is an API for your use case. There is a C++ API for Analytic Executables (user defined functions like special aggregates and table functions, but these aren't going to get you a result set by themselves). I've previously just made an ODBC connection to get to a Netezza instance and execute queries (albeit within C#, not C++). For data migration, especially between two disparate databases, I've typically written the data to a flat file of one sort or another (.csv, tab delimited text file, etc.) and then consumed that file again within my program and pushed that data to the table within the destination db (using a second ODBC connection, and with Bulk Copy (BCP) for SQL server if this is the destination db).
MSDN has some example code for connecting to a db via ODBC using C++ HERE.

Is there a way to capture the executed SQL statements in Hibernate and Ibatis then save them to database?

One of the requirements on my current project is to be able to log the SQL statement generated by either Hibernate or Ibatis, and save them to a specific table (on SQLServer), so an administrator can come back and see what queries were run and who ran them, or even reuse the statements on demand. While I don't agree with this approach, I would like to know if there actually exists a library that can achieve this. I am using Spring framework for my web application.
There are 3rd party SQL Server tools that can capture T-SQL statements, and store them for later manipulation and analysis, such as Idera SQL Compliance Manager and ApexSQL Comply
Disclaimer: I work as a Product Support Engineer at ApexSQL
If you want to catch all queries of a middleware like Hibernate or Ibatis, the simplest way is to use SQL Server profiler or to create a trace with SQLTrace stored procedures (sp_trace_create, sp_trace_setevent).
With SQL Profiler you can save traces directly to a table, with SQLTrace stored procedure who produces a trc file, you will have to insert them in your table with sql statements.
they are lot of examples on the web, for example here
SQL Profiler have an option to generate the SQLTrace SQL script once you have defined your trace (File/export)
The SQL Profiler is in the developper edition but not in the Express edition.
SQLTrace stored procedures are in all editions (IIRC).
You can generate the trace script on your developper edition and run it on your express edition.
You can also create a stored proc that create and start the trace on server startup.
You can do it on the server, with database audit if you have the enterprise edition of SQL Server. Or you can use Extended Events. You just need to filter by the application name, which should mention the ORM. To help you further, please provide the version and edition of SQL Server.
I know a way though it's not easy to implement. Make a custom DataSource - a wrapper over a real DataSource like Apache BasicDataSource. It will intercept getConnection calls and wrap Connection returned by the target DataSource. This wrapped Connections will intercept createStatement / createPreparedStatement calls and wrap Statements / PreparedStatements returned. The Statement wrapper can now intercept SQL executions and log them.
Yet another way to do it would be to enable SQL statement logging in the Hibernate configuration settings, and then "hoover" the statements out of the log files.
But I think that a database-server-side solution is probably the best, because it can also captures queries and updates performed using the database's interactive query tool.

How do I implement the UnityJDBC in my Java project?

i have a project am working on, its all about querying a data from multiple databases from different vendors (i mean querying databases like mysql, hsqldb, microsoft sql, oracle, etc at the same time using one query statement).
Though i have achieved this by loading each driver of the database connector sequentially and execute the query sequentially across the databases. But the project architecture is such that when i sent a query statement, it shouldgo simultaneously to each database and retrieve the item ifavailable in all databases involved.
I came across this unityjdbc software, a mediation software but dont know how to implement it in my java source file so that to achieve my aim. I have read the unityjdbc user manual but is not clear and straight-forward.
Please can anyone advise how toimplement this unityjdbc driver in my java application and use it to successful query multiple databases.
Suggestions for any other way to simultaneously query their multiple databases with a single statement would also be welcome.
UnityJDBC allows you to query multiple databases in one SQL query. You cannot do this using separate threads as you would then be responsible for merging the data from the multiple databases yourself in your Java program.
The setup steps are easy:
Use the SourceBuilder application to specify the JDBC connection information to your databases.
Test a sample query that accesses multiple databases. Standard SQL is supported. To reference tables in different databases use databaseName.tableName in your FROM clause.
For example:
SELECT *
FROM Database1.Table1 T1 INNER JOIN Database2.Table2 T2 ON T1.id = T2.id
The SourceBuilder application will provide an XML configuration file as output often called sources.xml. To use this in your own Java program or any software that supports JDBC the connection URL is: jdbc:unity://sources.xml You may specify an absolute or relative path to the sources.xml file.
There is documentation on their site at http://www.unityjdbc.com/support/ or contact them for free support.
Another way to get started quickly is to use the MultiSource SQL Plugin that comes with the open source query software SQuirreL SQL. The plugin will allow you to query any number of databases using SQL in SQuirreL and will generate the XML configuration files for you to use in other programs. The plugin is open source and free. The plugin also supports querying and joining NoSQL databases like MongoDB with relational databases such as MySQL and Postgres.
You don't need UnityJDBC for what you want to do, if you've already managed to load all the db-specific JDBC drivers.
Instead, you should look at doing each query in a separate thread. That way, you don't need to wait for one database to return its results before querying the next one.

Bulk Row Transfer between Oracle Databases with a Select Filter

Basically, I'm trying to selectively copy a table from one database to another. I have two different [Oracle] databases (e.g., running on different hosts) with the same schema. I'm interested in a efficient way to load Table A in DB1 with the result of running a select on Table A in DB2. I'm using JDBC, if that's relevant.
Use a database link, and use create table as select.
create database link other_db connect to remote_user identified by remote_passwd using remote_tnsname;
create table a as select * from a#other_db;
If the databases are from the same vendor they usually provide a native way to make a view
of a table in another database. in which case, a "select into" query will do it no problem
Oracle, for example, has the database link which works pretty well.
Outside of that you are going to have to make a connection to each database and read in
from one connection and write out to the other.
There are tools like Oracle's ODI that can do the legwork, but they all use the same
read in, write out model
You may not even need to move that data. Maybe you can just select across the database link.

Categories

Resources