2013-10-23 34 views
3

我一直在從PostgreSQL 9.1遷移到Oracle 11gR2,並遇到了一個奇怪的問題。爲什麼我的JDBC更新無法正常工作?

我一直在運行的代碼,當客戶已添加到我們的ERP系統,更新的表。這段代碼自3月份以來一直在PostgreSQL上運行,沒有任何問題。現在我正在切換到Oracle,相同的代碼不再更新。

原始代碼

update = "UPDATE store SET added_customer = 'y' WHERE order_id = ?"; 
try { 
    PreparedStatement pStmnt = getConn().prepareStatement(update); 
    pStmnt.setString(1, orderId);    
    results = pStmnt.executeUpdate(); 

    if (results > 0) { 
     added = true;     
    }  
} catch (SQLException ex) { 
    LOGGER.error(ex.toString()); 
} 

沒有異常被拋出,但沒有數據變化,所以我認爲 「自動提交不得工作,讓手動提交」:

新代碼

update = "UPDATE shop_ca_orders SET added_customer = 'y' WHERE order_id = ?"; 
try {     
    getConn().setAutoCommit(false); //Added 
    PreparedStatement pStmnt = getConn().prepareStatement(update); 
    pStmnt.setString(1, orderId);    
    results = pStmnt.executeUpdate(); 

    if (results > 0) { 
     added = true; 
     getConn().commit(); //Added 
     getConn().setAutoCommit(true); //Added 
    }  
} catch (SQLException ex) { 
    LOGGER.error(ex.toString()); 
} 

仍然沒有運氣,所以我在0123後增加聲明,並發現我返回0,因此沒有記錄正在更新。

有趣的,所以我想通過SQL Developer中的查詢,並將其正確更新。這使我想起了我的問題:

爲什麼我無法通過JDBC來更新我的數據庫?

必要的數據:

  • order_id是類型VARCHAR(255 BYTE)
  • 爪哇7
  • 甲骨文11gR2的上亞馬遜RDS運行
  • 從PostgreSQL的9.1遷移在Heroku運行
  • 論的PostgreSQL order_idcharacter varying(255)

EDIT

小模式更改未被發現並導致錯誤,其中訂單ID實際上是該人的姓名,而不是訂單ID。 Bonehead錯誤在我的結尾。無論如何,現在我已經解決並拉動正確的訂單ID,我發現我掛在executeUpdate。目前正在處理這個問題。如果我無法解決,我可能會創建一個新問題。

回答

1

什麼getConn()回報?我懷疑每次都是不同的(彙集?)連接。

此:

getConn().setAutoCommit(false); //Added 
PreparedStatement pStmnt = getConn().prepareStatement(update); 

應該會顯示爲:每一次,那麼你已經有了問題

Connection c = getConn(); 
c.setAutoCommit(false); //Added 
PreparedStatement pStmnt = c.prepareStatement(update); 

即如果getConn()返回不同的連接。

+0

我從來沒有考慮過,讓我給它一個旋轉 –

+0

仍然返回0爲更新。 getConn()返回在類構造函數中創建的連接對象。沒有使用池。 –

+0

儘管這不是一個直接的答案,但它指出了我需要調查才能找到答案。謝謝 –

0

我通過這個問題前幾年去了,當我在WHERE子句中,使用令牌使用的字符串值,它並沒有奏效。順便說一句,這也是一個Oracle數據庫(10G)

最後,我放棄了,並改變了代碼來串聯值,而不是記號化它

update = "UPDATE shop_ca_orders SET added_customer = 'y' WHERE order_id = ?"; 
try {     
    getConn().setAutoCommit(false); //Added 
    PreparedStatement pStmnt = getConn().prepareStatement(update); 
    pStmnt.setString(1, orderId);    
    results = pStmnt.executeUpdate(); 

    if (results > 0) { 
     added = true; 
     getConn().commit(); //Added 
     getConn().setAutoCommit(true); //Added 
    }  
} catch (SQLException ex) { 
    LOGGER.error(ex.toString()); 
} 

update = "UPDATE shop_ca_orders SET added_customer = 'y' WHERE order_id = ' + order_id + '"; 
try {     
    getConn().setAutoCommit(false); //Added 
    PreparedStatement pStmnt = getConn().prepareStatement(update); 
    results = pStmnt.executeUpdate(); 

    if (results > 0) { 
     added = true; 
     getConn().commit(); //Added 
     getConn().setAutoCommit(true); //Added 
    }  
} catch (SQLException ex) { 
    LOGGER.error(ex.toString()); 
} 

這對我來說訣竅...這不是最優雅的解決方案,但是是一個解決方法

======================更新1 ========================= ===

我已經做了一些更多的研究,因爲我也面臨這個問題,仍然沒有得到有效的答案

看起來像甲骨文司機希望你通過類似長度的字符串桌定義。這隻發生在固定長度的列(如CHAR)上,VARCHAR列似乎不受此影響。

這意味着,如果order_id是一個CHAR(10),那麼你應該填充你的字符串來完成列的長度。更好的方法是修剪數據庫值以匹配令牌值。

update = "UPDATE shop_ca_orders SET added_customer = 'y' " + 
     " WHERE LTRIM(RTRIM(order_id)) = ?"; 
try {     
    getConn().setAutoCommit(false); //Added 
    PreparedStatement pStmnt = getConn().prepareStatement(update); 
    pStmnt.setString(1, orderId);    
    results = pStmnt.executeUpdate(); 

    if (results > 0) { 
     added = true; 
     getConn().commit(); //Added 
     getConn().setAutoCommit(true); //Added 
    }  
} catch (SQLException ex) { 
    LOGGER.error(ex.toString()); 
} 
+2

我會擔心SQL注入,因爲它會在沒有檢查的情況下傳遞order_id。 –

+0

是的。就我而言,標識符在控制器上得到驗證,然後傳遞給業務邏輯,所以沒有問題。不幸的是,我無法得到更好的方法,因爲標記化查詢總是返回/更新零結果 –

+0

添加了我對此做出的發現...希望它有幫助 –

0

所以我的問題是雙重的:

首先我有一個問題,我最初的結果集。在遷移過程中,刪除了一列,我認爲所有引用的列都在代碼中進行了更改,但缺少一列。一旦解決了這個問題,訂單ID就能正確工作,並嘗試更新數據庫。

第二個問題是掛在更新上的數據庫出現問題。事實證明,掛起是由SQL Developer在數據庫(或表,不知道哪個)上持有鎖定引起的 - 一旦我關閉了SQL Developer,立即完成更新並且事情按預期進行。

相關問題