2013-09-29 116 views
0

我對我的問題沒有很好的答案,發現如何去做。只有在記錄不存在的情況下,纔會將記錄插入到表中:PL/SQL - 只在記錄不存在的情況下插入記錄

1)在您的模式上創建或替換函數(這是檢查2個參數,您可以將其設置爲與您一樣多希望)PL/SQL是非常具體的,複製和粘貼,因爲我寫了應該編譯成功。花了很多努力才使語法恰到好處。該函數檢查要寫入的表以及要檢查的相應列名是否已經一起存在。

create or replace function Found(
    var1 type, 
    var2 type) 
return number 
is    
    numberOfSelectedRows number := 0; 
begin 
    select count(*) 
    into numberOfSelectedRows 
    from TABLE 
    where COLUMN_NAME = var1 
     and COLUMN_NAME = var2; 

    return numberOfSelectedRows; 
end Found; 

2)編寫java執行pl/sql函數:這是用NetBeans完成的。當單擊該按鈕時,它將從其他表中加載FORM數據,並確定該表中是否已存在要插入的表中的記錄。

try {    
     DriverManager.registerDriver (new oracle.jdbc.OracleDriver()); 
     con = DriverManager.getConnection(""+LOGIN.url+""); 

     String str1 = jTextField_VariableName.getText(); 
     String str2 = jTextField_VariableName.getText(); 

     String q = "insert into TABLE (var1 type, var2 type) VALUES ('"+str1+"', '"+str2+"')" ; 

     cs = con.prepareCall("{?=call Found(?, ?)}");    // cs = CallableStatement - defined in class CallableStatement cs = null; 

     cs.setString(2, str1); 
     cs.setString(3, str2); 
     cs.registerOutParameter(1, Types.INTEGER); 
     cs.execute(); 

     if(cs.getInt(1)>= 1) 
      { 
      JOptionPane.showMessageDialog(null, " this record already exists"); 
      } 
     else 
      { 
      try{ 
       DriverManager.registerDriver (new oracle.jdbc.OracleDriver()); 
       con = DriverManager.getConnection(""+LOGIN.url+""); 

       pst = con.prepareStatement(q); 

       pst.execute(); 

       }catch(SQLException ex) {Logger.getLogger(REGISTER_STUDENT.class.getName()).log(Level.SEVERE, null, ex);} 
      } 

     } catch (SQLException ex) {Logger.getLogger(REGISTER_STUDENT.class.getName()).log(Level.SEVERE, null, ex);}  
+2

你可以看看Oracle [MERGE](http://www.oracle-bas e.com/articles/10g/merge-enhancements-10g.php)聲明。 – user75ponic

回答

2

只要做到:

String q = 
"insert into TABLE (var1, var2) " + 
"SELECT ?, ? FROM dual "+ 
"WHERE NOT EXISTS(
" SELECT 1 FROM table 
" WHERE var1 = ? AND var2 = ?)"; 
pst = con.prepareStatement(q); 
pst.setString(1, str1); 
pst.setString(2, str2); 
pst.setString(3, str1); 
pst.setString(4, str2); 
int status = pst.execute(); 
if(status > 0) 
    System.out.println("New row inserted"); 
else 
    System.out.println("Row already exists, insert skipped"); 



---編輯---

INSERT INTO .... SELECT ....語法支載在大多數DBMS,看到這個鏈接查看更多細節:http://www.w3schools.com/sql/sql_insert_into_select.asp
它只是從一個表中選擇行並將結果插入到另一個表中。

dual是Oracle數據庫的一個「虛擬」的表,它有一列一列,這裏有一個例子:http://www.sqlfiddle.com/#!4/d41d8/11
DUAL表是在許多情況下,有益的,我們需要創建一個列有一些價值。在其他數據庫中 - 特別是在MySql和PostGreSQL中 - 這可以用簡單的SELECT x, y完成,不幸的是Oracle不支持這種語法,我們必須使用SELECT x, y FROM dual

在我們的情況下,它被用來創建值行,我們要插入到表:

INSERT INTO table 
SELECT x, y FROM dual; 

然而,行必須只插入時的一些條件滿足 - 是這樣描述的條件在WHERE子句:

INSERT INTO table 
SELECT x, y FROM dual 
WHERE NOT EXISTS( 
    SELECT 1 FROM table 
    WHERE var1 = X and var2 = Y 
) 

如果子查詢SELECT 1 FROM ...返回行(行存在) - 則條件NOT EXISTS ...是假的,SELECT x, y回報沒有(空結果),並且沒有任何內容被插入到表格中。另一方面,當子查詢找不到任何東西時,整個條件成立,並且SELECT x,y語句創建一個包含兩列的行:X + Y,並將該行插入表中。

在PreparedStatement(在java代碼中)我們正在使用?而不是X,Y變量 - ?是一個placeholder(一個替代變量)。此鏈接:http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html詳細描述PreparedStatement如何工作以及如何使用替代變量。

說它只是 - 我們的查詢具有4個佔位符?

insert into TABLE (var1, var2) 
SELECT ?, ? FROM dual 
WHERE NOT EXISTS(
    SELECT 1 FROM table 
    WHERE var1 = ? AND var2 = ?) ; 

和的setXXX語句結合值來連續佔位符:

pst.setString(1, str1); 
pst.setString(2, str2); 
pst.setString(3, str1); 
pst.setString(4, str2); 

從而結合值來替代標誌,查詢(其是後最後執行)看起來像:

INSERT INTO TABLE (var1, var2) 
SELECT 'str1', 'str2' FROM dual 
WHERE NOT EXISTS(
    SELECT 1 FROM table 
    WHERE var1 = 'str1' AND var2 = 'str2') ; 
+0

謝謝Kordirko,我之前問過這個問題,並且得到了一些關於我應該如何祈禱它可以工作的smartalek評論。我對PL/SQL幾乎沒有任何培訓,您能否推薦一個顯示此符號的好網站?謝謝 – user2826554

+1

@ user2826554我添加了一個shoth解釋,希望這有助於 – krokodilko

+0

好的,但是關於VALUES插入的部分在哪裏?知道一個顯示此符號的好頁面? – user2826554

相關問題