-1

I have 2 different databases. Actually the second database is with all the records that are identical to the first one. Mean when i create/delete/update any entry in the first database, then after a certain while it is visible in the second database table as well. Although there are some minor differences as well like two rows are different or additional in the first table.

My question is how to compare these two tables from two different databases in java.

I connect to the databases like this but i don't know how to proceed further. Any help would be appreciated

        String SQL_Statement = "SELECT * FROM Table_All_Customers";

        for (Connection con : getDBConnections())
        {

        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery(SQL_Statement);
        int count=0;
        int rowCount= 0;
        while (rs.next())
        {
            count+=1;
            rowCount+=1;
            String productNumber = rs.getString("Customer");
            System.out.println("This is the result ... " + rowCount + " :" + productNumber);
        }
    }

With the above code, i am just fetching the data from the columns of these tables and printing them

the tables look like this

table 1 in database 1:

UserID  Customer    Order    number  
----------------------
2334e3    David       Pizza    2       
2334e4    David       Cola     3       
2334e5    Lisa        Cola     4       
2334e6     Lina       Pizza    5      
2334e7    Greco       Cola     6       

table 1 in database 2:

 UserID   Customer    Order    number  
    ----------------------  
  2334e3  David       Pizza    2       
  2334e4  David       Cola     3       
  2334e5  Lisa        Cola     4       
  2334e6  Lina        Pizza    5       

My aim is to compare these two tables above to check if data is updated successfully in two different databases. Also is there any way to check the differences as well? How to achieve it via Java. Would be thankful for any help.

Updated:

I tried something like this but i am unable to compare the differences, is it possible to print the differences between two tables?

public static boolean isDBSame()
    {
        try
 {
        Connection con = DriverManager.getConnection(URL, userName, pass);
        Connection con2 = DriverManager.getConnection(URL2, userName, pass);
        Statement stmt = con.createStatement();
        Statement stmt2 = con2.createStatement();
        ResultSet rs = stmt.executeQuery(SQL_Statement);
        ResultSet rs2 = stmt2.executeQuery(SQL_Statement_2);
        int count = 0;
        int rowCount = 0;
        int firstDB_count = 0;
        int firstDB_rowCount = 0;
        List<String> tags = new ArrayList<String>();
        List<String> tags2 = new ArrayList<String>();
        List<String> tags3 = new ArrayList<String>();
        Set<String> ad = new HashSet<String>(tags);
        Set<String> bd = new HashSet<String>(tags2);
        while (rs.next())
        {
            String Customer = rs.getString(1);
            System.out.println("This is the content of 1st database: " + rowCount + " : " + Customer.toString());
            count += 1;
            rowCount += 1;
            tags.add(rs.getString("UserID"));
   while (rs2.next())
                {
String Customer2 = rs2.getString(1);
tags2.add(rs2.getString("CUserID"));
 }

        }
        for (String e : tags2)
        {
            System.out.println("This is the second database e.... " + e);
        }
        if (tags.equals(tags2))
        {
            System.out.println("Hi ");
            System.out.println("Content is same...");
            return true;
        }
        else
        {
            System.out.println("Content is not same and check properly....... " );
        }
    }
    catch (Exception e)
    {

        System.out.println("It is false...");
        System.out.println(e.toString());
    }
    return false;
}


       

Even i tried this

Set<String> ad = new HashSet<String>(tags);
Set<String> bd = new HashSet<String>(tags2);
ad.removeAll(bd);

But it result in false or true. Is there anyway that i can print the difference between two lists? Also any efficient way to compare different columns of two different tables in the 2 different databases.

Rio
  • 347
  • 3
  • 6
  • 20
  • How many rows do these tables have? Do you need to compare them programmatically? Does the comparison need to be repeated often, or is it a one-time effort? – Adriaan Koster Jun 20 '23 at 09:26
  • @AdriaanKoster Thank you for the reply. Yes i want to do it programmatically in java. and the comparison is needed to be done every 5 minutes to check if the data is sync correctly in the second database. – Rio Jun 20 '23 at 09:30
  • @AdriaanKoster the table has hardly 30 to 60 rows at the moment. – Rio Jun 20 '23 at 09:34
  • read set one in one list, read set two in a different list, compare the content of the lists – Stultuske Jun 20 '23 at 09:40
  • @Stultuske well if there are 5 to 6 different columns in each table, then how to do it? Can you show me with the code . It would great help. – Rio Jun 20 '23 at 09:45
  • you are aware an equals method can compare more than one single field, I assume? – Stultuske Jun 20 '23 at 09:46
  • What is the primary key of these tables? Can you use an ORM framework like JPA + Hibernate to map the data to objects? Or do you need to use JDCB and ResultSet as shown? – Adriaan Koster Jun 20 '23 at 09:59
  • @AdriaanKoster USERID is the primary key in both tables and they are identical in both tables of both databases. – Rio Jun 20 '23 at 10:04
  • @AdriaanKoster i can only use java code to achieve this or some oracle sql commands. – Rio Jun 20 '23 at 10:05
  • @Rio so what is the problem with reading the data into lists and compairing the lists contents? – Stultuske Jun 20 '23 at 11:53
  • @Stultuske it might be a good solution. Can you help me to give a solution in code form that i can try? I can try to compare 1 or 2 columns from that database tables. – Rio Jun 20 '23 at 13:04
  • @Rio creating the combination of equals and hashcode methods is part of the basics of OO programming in Java. If you need help with that part, I would recommend not to dabble with databases just yet. – Stultuske Jun 21 '23 at 06:36
  • @Stultuske I did but i am not getting my desired output. I updated my efforts and question as well sir. – Rio Jun 21 '23 at 08:23
  • yess ... this -> (tags.equals(tags2)) is not how you compare the content of Lists. – Stultuske Jun 21 '23 at 11:59
  • If you're using Oracle, have you considered using a database link to connect the two databases directly, and then compare them with a query, instead of in Java? https://docs.oracle.com/cd/B13789_01/server.101/b10759/statements_5005.htm – FrustratedWithFormsDesigner Jun 21 '23 at 12:56

2 Answers2

0

The more convenient way to do this is by having an Orignal table in your single database and make another table with similar characteristics and then compare them but for your scenario.

The easy way to do this is by making two separate connection to your 2 databases in single method like this:

    public boolean isSame(){
        try{
           Connection con = DriverManager.getConnection(URL, userName, pass);
           Connection con2 = DriverManager.getConnection(URL, userName, pass);
           Statement stmt = con.createStatement();
           Statement stmt2 = con2.createStatement();
           ResultSet rs = stmt.executeQuery(SQL_Statement);
           ResultSet rs2 = stmt2.executeQuery(SQL_Statement);
              int count=0;
              int rowCount= 0;
              while (rs.next())
              {
                 while(rs2.next()){
                      String Customer = rs.getString(1);
                      String Customer2 = rs2.getString(1);
                      if(Customer.equals(Customer2)){
                          return true;
                      }
                 }
            }
       } catch(Exception e){
            System.out.println(e.toString())
     }
     return false; 
}

Con and Con2 will be two separate connections for your database and then you can create separate statement and result set for them. In getting the values you will get the required one's and compare them and can use && operator to compare many at once which will solve your problem.

Levi
  • 19
  • 6
  • when i tried to print the content, it always print the content of second database. Also if i use the public boolean isSame(), then i can't run it from main method. but if i add the static keyword, then i am able to run but i cannot print the data from first database table. it somehow always get the connection to second database. seems the first connection is closed. Can you please help me with somehow to print the content of both databases in your above solution?. i think its a small issue – Rio Jun 20 '23 at 11:11
  • if you can share the piece of code that you are running right now then maybe I can look for any mistake because I ran this before posting here and it was working fine for me. – Levi Jun 20 '23 at 11:20
  • I updated my question. I added what i tried with your solution. Somehow i am able to print the data from both database tables. Is there any way to print the content which is similar in both tables and the content which is different or extra in both tables? This way i will get my solution in final stage. Any idea would be greatly appreciated. – Rio Jun 20 '23 at 13:03
0

You could structure your code a bit better. For example by breaking down what you are trying to achieve into logical steps. It works better than trial-and-error development:

  1. Read the results from both databases, ordered by UserID
  2. Compare the row and column counts of both results and exit with failure if they differ
  3. Iterate over both results simultaneously until there is a difference, or the end of both lists is reached.
  4. Within the iteration, take the next row from each result
  5. Iterate over the columns of both rows
  6. Compare the two column values and exit with failure if they are not equal
  7. On reaching the end of the result iteration, exit with success

Something like this (untested):

class DatabaseComparisonUtility {

    private ResultSet resultSet1;
    private ResultSet resultSet2;
    private int columnCount;
    private boolean equals;

    public boolean areSame(Database db1, Database db2, String query) throws Exception {
       
        equals = true;

        readResultSets(db1, db2, query);

        checkDimensions();

        while (equals && resultSet1.next() && resultSet2.next()) {
            compareRows();
        }

        return equals;
    }

    private void readResultSets(Database db1, Database db2, String query) throws Exception  {
        resultSet1 = readResultSet(db1, query);
        resultSet2 = readResultSet(db2, query);
    }

    private ResultSet readResultSet(Database db, String query) throws Exception  {
        Connection conn = DriverManager.getConnection(db.getUrl(), db.getUserName(), db.getPassword());
        Statement stmt = conn.createStatement();
        return stmt.executeQuery(query);
    }

    private void checkDimensions() {

        columnCount = getColumnCount(resultSet1):
        equals = equals && (columnCount == getColumnCount(resultSet2));

        int rowCount = getRowCount(resultSet1);
        equals = equals && (rowCount == getRowCount(resultSet2));
    }

    private int getColumnCount(ResultSet resultSet) {
         return resultSet.getMetaData().getColumnCount();
    }

    private int getRowCount(ResultSet resultSet) {
         resultSet.last();
         int rowCount = resultSet.getRow();
         resultSet.first();
         return rowCount;
    }

    private void compareRows() {
        for(int column = 1; column <= columCount; column++) {                
            equals = equals && equalColumns(column);
        }
    }

    private boolean equalColumns(int column) {       
        String value1 = resultSet1.getString(column);
        String value2 = resultSet2.getString(column);
        equals = equals && (value1.equals(value2));
    }
}

I am assuming here that it is ok to compare the String representation of your column values, which should be ok for most cases.

The statements like equals = equals && (rowCount == getRowCount(resultSet2)) are making sure the existing value of equals is not overwritten. To assure that once equals becomes false, subsequent checks will not make it true again.

The part rowCount == getRowCount(resultSet2) is a boolean expression which evaluates to true if the two rowCounts are equal and false otherwise.

You need to create the Database class yourself, containing the fields needed to connect to the database (url, userName, password).

The SQL query needs to sort the rows by UserId, so:

"SELECT * FROM Table_All_Customers ORDER BY UserID"

Otherwise the order of the results is unspecified and comparing them sequentially might fail.

Adriaan Koster
  • 15,870
  • 5
  • 45
  • 60
  • thank you for the help. this line is giving the error. equals = equals && (rowCount <> getRowCount(resultSet2)); . – Rio Jun 21 '23 at 14:30
  • Yes, that should be `==`, I thought I fixed that but apparently not. Now fixed above. If I would have needed `<>` that should have been expressed as `!=` in Java, don't know where my head was at ;-) – Adriaan Koster Jun 21 '23 at 15:15
  • Can you help me to solve the last piece of puzzle i guess. I connec to the database like this "Connection con = DriverManager.getConnection(URL, userName, pass);" But you mentioned in methods (Database db1, Database db2, String query) . Query is easy for me . but the Database db1 and Database db2 confuses me. It might seems very basic. but can you help me what should i insert here? Like what should i enter for Database db1 and db2? – Rio Jun 22 '23 at 07:41
  • I intended a wrapper class called 'Database' which contains the fields url, userName, password. You can create that and populate it with the values you need. Or you can replace the Database parameters with three String parameters. Left as an excercise for the reader ;-) – Adriaan Koster Jun 22 '23 at 08:30
  • I fixed a bug in compareRows: `for(int column = 1; column <= columCount; column++)` changed `<` to `<=` – Adriaan Koster Jun 22 '23 at 08:38
  • I would be grateful from my heart if you show me either way with the code. Either with the Database wrapper class or using Strings. Can you help me by providing the demo example. I would be really thankful for this help. I tried to change the params to string but failed miserably. – Rio Jun 22 '23 at 09:13
  • You should really be able to figure this out yourself. If not, I suggest getting some basic Java training first, or you will not be able to do anything autonomously. In this case just replace all `Database db` with `String url, String userName, String password`. Where the db is passed into a method replace it with `url, userName, password`. Where fields are read replace 'db.getUrl()' with `url` etc. In the part of the code where you have db1 and db2, distinguish the url/userName/password fields in the same way by suffixing with 1 or 2. – Adriaan Koster Jun 22 '23 at 11:55