Joining two databases in Java with mysql queries? - java

I am trying to run an SQLquery in a java application. The sqlquery connects two databases (not on the same server). Is it correct what I am doing here:
the public function has:
private DatabaseData externaldb = new DatabaseData("com.mysql.jdbc.Driver",
"...", "...", "...");
private DatabaseData localdb = new DatabaseData("com.mysql.jdbc.Driver",
"...", "...", "...");
private Connection externalconnection = null;
private Connection localconnection = null;
function(externalconnection, c_id, u_d);
the called function is:
private int function(Connection externalconnection, String c_Id, String u_Id)
throws SQLException{
String query ="SELECT A.v_id, COUNT(I.v_id) AS v_count "
+ "FROM externaldb.video_interaction I"
+ " INNER JOIN localdb.video_additional A ON A.v_id = I.v_id"
+ " WHERE I.c_id='" + c_id + "' AND I.user'" + u_Id + "';";
Statement stmt = externaldb.createStatement();
ResultSet rs = stmt.executeQuery(query);
int counter = 0;
if (rs.next()){
counter = rs.getInt("video_count");
}
return counter;
}
Thank you!

You have two connections, you have two databases. Server local must have access to external and external to local. Then, create FEDERATED table, for example:
CREATE TABLE federated_table (
id INT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
other INT(20) NOT NULL DEFAULT '0',
PRIMARY KEY (id),
INDEX name (name),
INDEX other_key (other)
)
ENGINE=FEDERATED
DEFAULT CHARSET=latin1
CONNECTION='mysql://fed_user#remote_host:9306/federated/test_table';
(Before MySQL 5.0.13, use COMMENT rather than CONNECTION.)
Source from: MySQL Cross Server Select Query
More informations: https://dev.mysql.com/doc/refman/5.7/en/federated-create-server.html

Related

Creating a unique listing_no (Java/PostgreSQL)

I am working on a option in a Menu function that posts the car for the sale in a database. The option asks for the user to enter the year, make, condition and price, which is then inserted into the table car_sale in the database. However, a unique listing_no must also be generated during this option. I cannot define my tables to uniquely generate the 10 digit number the option but I must code the program to insert uniquely generated listing_no. Below you will find the code of me trying to do this, however the code only works in Oracle but I cannot use Oracle. I can only PostGreSQL and Java. Therefore, my problem arises as the functions and relations I am using cannot be used in PostGre.
Code to Generate Listing No:
public int generateListingNo() throws SQLException
{
int listingSeq = 0;
Statement select = connection.createStatement();
result = select.executeQuery("select (to_char(sysdate,'yyyymmdd')||AUDIT_SEQ.NEXTVAL)valnext from dual");;
if(result.next())
{
listingSeq = result.getInt(1);
}
int seq = listingSeq;
return seq;
}
Code in The Option Function to insert the lisitng_no generated from generateListingNo()
public void option() throws SQLException
{
int listing_no = generateListingNo();
// insert information into books_for_sale table
sql_insert = "INSERT INTO car_sale VALUES(" + listing_no +", "
+ "'" + year + "'" + ", " +
"'" + make + "'" +", " +
"'" + condition + "'" + ", "
+ price + ")";
Erros I am Getting:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: relation "dual" does not exist
Position: 69 at
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:217)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:421)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:318)
at org.postgresql.jdbc.PgStatement.executeQuery(PgStatement.java:281)
Creating the car_sale table
create table car_sale(
listing_no int not null,
year varchar not null,
make varchar not null,
condition varchar not null,
price decimal(12,2) not null,
primary key (listing_no),
Change you query for generateListingNo as below:
select q from (select (to_char(now(),'yyyymmdd') || NEXTVAL('AUDIT_SEQ') )q )sq
or
select (to_char(now(),'yyyymmdd') || NEXTVAL('AUDIT_SEQ')) as newseqval
or on your cocde:
public int generateListingNo() throws SQLException
{
int listingSeq = 0;
Statement select = connection.createStatement();
result = select.executeQuery("select (to_char(now(),'yyyymmdd') || NEXTVAL('AUDIT_SEQ')) as newseqval");;
if(result.next())
{
listingSeq = result.getInt(1);
}
int seq = listingSeq;
return seq;
}
Since you dont have sequence :
Either create sequence using below query:
CREATE SEQUENCE public."AUDIT_SEQ"
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;
or use UUID:
public String generateListingNo() throws SQLException
{
return UUID.randomUUID().toString();
}
your table structure will need to change :
create table car_sale(
listing_no varchar not null,
year varchar not null,
make varchar not null,
condition varchar not null,
price decimal(12,2) not null,
primary key (listing_no),
For PostgreSQL, you have to call query this way from java :
SELECT nextval('ACCOUNT_TRANSACTION_NO')

Temporory tables using Spring's jdbc template

I'm facing an issue executing a very long query using spring jdbcTemplate. The query contains multiple DECLARE statements, multiple CREATE temp tables and in the end a SELECT statement which gets data by joining multiple tables as well as DROP statements. When I run this query directly in SQL Management studio, the query runs perfectly fine and returns me the data. However when I run the exact same query using spring's jdbc template there is no data returned.
Edit: I can not post exact query I'm using. But below is the template of how the query may look.
public class SpringJdbcExample{
public static final String sql = "DECLARE "+
"#XYZ DATETIME='1/31/2016', " +
"#ABC UNIQUEIDENTIFIER='', " +
"#var1 VARCHAR (1)='F', " +
"#var2 UNIQUEIDENTIFIER = NULL " +
"DECLARE #id1 INT, #id2 INT, #id3 Int "+
"SELECT #id1=(SELECT id1 FROM table1 WHERE XYZ=#XYZ) "+
"SELECT #id2=(SELECT id2 FROM table2 WHERE ABC=#ABC) " +
"SET NOCOUNT ON "+
"SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED "+
"CREATE TABLE #temp1 (var1 INT, var2 INT, var2 INT, var4 varchar(20) ) "+
"CREATE TABLE #temp2 (var1 INT,var2 INT, var3 DATETIME, var4 varchar(20)) "+
-- More Create temp tables
-- Insert into temp tables from various DB tables
-- single Select statement from temp tables
-- Drop temp tables
"; // end of the string
private JdbcTemplate jdbcTemplate;
public SpringJdbcExample (JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
public List<String> getData(){
// MapSqlParameterSource
MapSqlParameterSource params = new MapSqlParameterSource("someParams", "someValues");
jdbcTemplate.query(sql,params);
}

Values Not Being Inserted with prepareStatement in Derby Database

I've created a very simple table, and am attempting to insert into it. The table exists, but nothing I try to insert sticks; the resultSet is always null. I think I'm auto-incrementing my primary key correctly. Any ideas? Thank you!
String createGenreTableSQL = "CREATE TABLE Genre (GenreID INTEGER NOT NULL GENERATED ALWAYS " +
"AS IDENTITY (START WITH 1, INCREMENT BY 1), genreName varchar(60))";
statement.executeUpdate(createGenreTableSQL);
String prepGenreInsert = "INSERT INTO Genre(genreName) VALUES (?)";
psInsert = conn.prepareStatement(prepGenreInsert);
allStatements.add(psInsert);
psInsert.setString(1,"Television");
psInsert.setString(1,"Movies");
psInsert.setString(1,"VideoGames");
psInsert.setString(1,"Animes");
String fetchAllDataSQL = "SELECT * from Genre";
resultSet = statement.executeQuery(fetchAllDataSQL);
while (resultSet.next()) { //resultSet shows null
int genreID = resultSet.getInt("genreID");
String genreName = resultSet.getString("genreName");
System.out.println("GenreID:" + genreID + " Name: " + genreName);
}
The setString method simply binds the given value to the given parameter index. It does not actually execute the query. I believe what you want to do is
psInsert.setString(1,"Television");
psInsert.execute();
psInsert.setString(1,"Movies");
psInsert.execute();
psInsert.setString(1,"VideoGames");
psInsert.execute();
psInsert.setString(1,"Animes");
psInsert.execute();

H2 user-defined function is called many times

I'm using the h2 v1.3.176.
I have user-defined function which execute RECURSIVE query.
public static ResultSet getChildCategories(Connection connection, long categoryId) throws SQLException {
String sql =
"WITH RECURSIVE r(CATEGORY_ID, PARENT_ID) AS (\n" +
" SELECT CATEGORY_ID\n" +
" ,PARENT_ID\n" +
" FROM CATEGORY\n" +
" WHERE CATEGORY_ID = " + categoryId + "\n" +
" UNION ALL\n" +
" SELECT CATEGORY.CATEGORY_ID\n" +
" ,CATEGORY.PARENT_ID\n" +
" FROM CATEGORY, r\n" +
" WHERE CATEGORY.PARENT_ID = r.CATEGORY_ID\n" +
")\n" +
"SELECT CATEGORY_ID FROM r";
ResultSet resultSet = connection.createStatement().executeQuery(sql);
SimpleResultSet rs = new SimpleResultSet();
rs.addColumn("CATEGORY_ID", Types.INTEGER, 12, 0);
try {
while(resultSet.next()) {
rs.addRow(resultSet.getLong(1));
}
} finally {
resultSet.close();
}
return rs;
}
I have registered this function by following SQL.
create alias GET_CHILD_CATEGORIES for "com.myapp.db.function.Functions.getChildCategories";
My problem is the getChildCategories function will be called many times when I execute the following query.
SELECT DISTINCT B.BOOK_ID
,B.SERIES_ID
,B.TITLE
,B.ISBN
,B.VOLUME
,(
SELECT MAX(SAME_SERIES.VOLUME)
FROM BOOK SAME_SERIES
WHERE SAME_SERIES.SERIES_ID = B.SERIES_ID
AND SAME_SERIES.VOLUME IS NOT NULL
) AS VOLUME_COUNT
,B.PAGE_COUNT
,B.FILE_PATH
,B.SORTABLE_FILE_NAME
,B.SIZE
,B.HASH
,B.COVER_IMAGE_TYPE
,B.COVER_PAGE_NO
,B.COVER_LARGE_IMAGE_URL
,B.COVER_SMALL_IMAGE_URL
,B.COVER_CROP_COORD
,B.IS_ENCRYPT
,B.PUBLISHER_ID
,B.PUBLISHED_DATE
,B.CREATION_TIME
,B.LAST_MODIFIED_TIME
,B.NOTE
,B.IS_ISBN_SEARCH
,S.CATEGORY_ID
,S.TITLE
,BA.AUTHOR_ID
,BT.TAG_ID
FROM BOOK AS B
INNER JOIN SERIES AS S ON S.SERIES_ID = B.SERIES_ID
LEFT OUTER JOIN BOOK_TAG AS BT ON BT.BOOK_ID = B.BOOK_ID
LEFT OUTER JOIN BOOK_AUTHOR AS BA ON BA.BOOK_ID = B.BOOK_ID
WHERE
(
S.CATEGORY_ID IN (SELECT CATEGORY_ID FROM GET_CHILD_CATEGORIES(106))
And
S.IS_COMPLETION = 1
)
ORDER BY BA.AUTHOR_ID
Why do many times would be called this function?
Extracted from H2 documentation
A function that returns a result set can be used like a table.
However, in this case the function is called at least twice: first
while parsing the statement to collect the column names (with
parameters set to null where not known at compile time). And then,
while executing the statement to get the data (maybe multiple times if
this is a join). If the function is called just to get the column
list, the URL of the connection passed to the function is
jdbc:columnlist:connection. Otherwise, the URL of the connection is
jdbc:default:connection.
The first calls are only to retrieve the resultset column types. Then you have to check if the connection url is "jdbc:columnlist:connection". If true you have to return an empty result set with column list.
The connection url test is:
connection.getMetaData().getURL().equals("jdbc:columnlist:connection");

assigning variable in SQL query statement

In my current project, I have a function with argument (e.g., int badgID in the following code snippet). This function connects with Apache Derby database, creates table (e.g., FIRSTTABLE), then query to FIRSTTABLE table. The query statement uses function argument for query (e.g., ID = $badgeID ). My question:
Is ID = $badgeID the right way from a syntax point of view?. I have tried this case, but it is not working.
public void getprofile (int badgeID) {
// Create connection with Apache-Derby Database.
// Create table in Apache Derby datbase.
String createString = " CREATE TABLE FIRSTTABLE "
+ "(ID INT PRIMARY KEY, "
+ "PREF INT, "
+ " NAME VARCHAR(12))";
// SQL query on table
querystmt = "SELECT * FROM FIRSTTABLE WHERE ID = $badgeID"
}
that's php syntax...
in java you would write
String querystmt = "SELECT * FROM FIRSTTABLE WHERE ID = " + badgeID;

Categories

Resources