2013-07-22 85 views
0

我正在研究一種功能,我應該從oracle數據庫中獲取數據並將其插入MSSQL Server 2008數據庫使用Java編程(我知道有其他選擇像oracle金門,鏈接server.but這就是我要求做的)。我能夠從oracle服務器獲取數據並將其插入到sql server中。但問題在於裁員。即無論何時觸發或運行程序,都會插入重複記錄,因爲我應該每隔6,12,24小時執行一次。我不希望它發生。所以我如何避免它作爲源數據庫有不同的連接和目標數據庫是不同的連接。從Java程序中插入MS SQL Server 2008時避免重複的記錄

以下是密碼。我會喜歡你的幫助,避免重複插入數據。

/*TO Retrieve data from oracle database and insert it into sql server*/ 

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 
import java.util.Properties; 


public class states { 

    public static void main(String[] args) { 
     String statecode, statename; 
     try { 
      Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); 
      Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver") 
        .newInstance(); 

      // Connecting to Oracle 
      Connection oracleconn = DriverManager.getConnection(
        "jdbc:oracle:thin:@ipaddress:1521:orcl", 
        "uname", "pwd"); 
      // Connecting to SQL SERVER 
      Connection sqlconn = DriverManager 
        .getConnection("jdbc:sqlserver://localhost:1433;databaseName=dbname;user=sa;password=pwd;"); 
      System.out.println("connected"); 



      // create Statement for sql and oracle 

      /* 
      * A Statement is an interface that represents a SQL statement. You 
      * execute Statement objects, and they generate ResultSet objects, 
      * which is a table of data representing a database result set. You 
      * need a Connection object to create a Statement object. 
      */ 
      Statement oraclestatement = oracleconn.createStatement(); 

      Statement sqlstatement = sqlconn.createStatement(); 

      /* 
      * The ResultSet interface provides methods for retrieving and 
      * manipulating the results of executed queries, and ResultSet 
      * objects can have different functionality and characteristics. 
      */ 
      ResultSet oracle_rs = oraclestatement 
        .executeQuery("select substr(TRIIDTX,1,2),TRINAMETX from T_TRISTATE WHERE TRIIDTX IS NOT NULL AND TRINAMETX IS NOT NULL AND TRINAMETX not LIKE '%''%' ESCAPE '/'"); 
      System.out.println("TRICODETX TRINAMETX \n"); 

      // String dummytable="tbldummystate"; 

      while (oracle_rs.next()) { 

       System.out.println("  " + oracle_rs.getString(1) + "  " 
         + oracle_rs.getString(2) + " "); 

       // converting the string value into integer value 

       statecode = oracle_rs.getString(1); 
       statename = oracle_rs.getString(2); 

       sqlstatement 
         .executeUpdate("insert into tblStates(StateCode,StateName) values('" 
           + statecode + "','" + statename + "')"); 

       // sqlstatement.execute(); 


      }// end of while loop 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    }// end of 
} 
+0

,如果你不希望消除使用Java你可以宣佈在Access數據庫主鍵索引,趕上在代碼中的異常重複。 – haki

+0

我想通過java代碼來做到這一點,問題是我不能改變目標表的客戶端數據庫中的任何東西。它沒有任何限制。 – Mangesh

回答

0

也許使用MERGE會怎麼做呢?

喜歡的東西:

.executeUpdate(" 
MERGE INTO tblStates AS Target 
USING (VALUES ('"+ statecode + "','" + statename + "')) 
     AS Source (StateCode, StateName) 
ON Target.StateCode = Source.StateCode 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (StateCode, StateName) VALUES ('"+ statecode + "','" + statename + "'); 
)"; 

編輯:如果您想更新Statename的對,如果它在源表中可以前添加以下語句的改變已經存在於目標表StateCode WHEN NOT MATCHED條款:

WHEN MATCHED THEN UPDATE SET StateName = ('" + statename + "')"

+0

但這怎麼可能?當我的源數據庫使用另一個連接和語句並使用另一個連接和語句的目標。一個是oracle,另一個是sqlserver – Mangesh

+0

該查詢只使用與SQL Server的連接,並且只有在目標表中不存在'StateCode'提供的變量時才執行插入操作。我還沒有在Java中嘗試過它,只是在T-SQL中。 – jpw

+0

它的工作方式與您已經完成的插入操作相似,但MERGE會檢查該值是否已經存在,並且只在插入時才插入。 – jpw

0

之前做insert into tblStates...你可以做的sqlconn一個select並選中要插入的記錄是否確實已經存在。如果是這樣,則跳過insert,否則,執行insert

但是,這不是很有效率,因爲對於每個記錄,您將執行select。想象一張有100k行的表格...

爲了提高性能,你可以做以下事情。在迭代oracle_rs之前,將全部記錄從tblStates加載到List。由於沒有主鍵(根據您的意見),我建議您使用List<Foo>,其中您定義了一個名爲Foo的類,其中包含要插入到目標數據庫中的一行的值。這使您可以在目標數據庫中對內存進行內存檢查。如果您的內存集合包含您剛剛從源數據庫中獲取的記錄,請不要將其插入到目標數據庫中。

在僞代碼,它會大致是這樣的:

String selectAllQuery = "select StateCode, StateName from tblStates"; 
Statement selectAllstatement = sqlconn.createStatement(); 
ResultSet selectAllResultset = selectAllstatement.executeQuery(selectAllQuery); 

List<Foo> cache = new ArrayList<Foo>(); 
while (selectAllResultset.next()) { 
    cache.add(new Foo(selectAllResultset.getString("StateCode"), 
         selectAllResultset.getString("StateName"))); 
} 

while (oracle_rs.next()) { 
    statecode = oracle_rs.getString(1); 
    statename = oracle_rs.getString(2); 

    if (!cache.contains(new Foo(statecode, 
           statename))) { 
     sqlstatement.executeUpdate("insert into tblStates" 
      + "(StateCode,StateName) values('" 
      + statecode + "','" + statename + "')"); 
    } 
} 

隨着Foo類是這樣的:

public class Foo { 
    private String stateName; 
    private String stateCode; 
    // Insert constructor with two arguments 
    // Insert equals() implementation based on the two instance variables 
} 
+0

感謝您的解決方案。我會嘗試。如果你能給我一個很好的例子。因爲我對它很新穎。 – Mangesh

+0

我試過你的解決方案,但它也不工作,它重複插入重複的行,這是以前存在 – Mangesh

+0

然後肯定有錯誤的地方,也許你可以更新你的問題,或開始[代碼評論](http:// codereview.stackexchange.com/)以尋求建議/幫助。 – mthmulders