2013-10-17 66 views
10

使用AWS Redshift時,我注意到通過 從具有標識列的表中獲取最後一個插入的ID不能使用以下任一方法來完成JDBC驅動程序:通過JDBC從AWS Redshift檢索插入的標識值

RETURNING key word 

Statement.RETURN_GENERATED_KEYS 

如堆棧溢出項提到:

How to get a value from the last inserted row?

上述方法不可用,因爲Redshift(截至2013年10月17日)是基於PostgreSQL 8.0.2版構建的。請參閱以下鏈接如下 文檔:

http://docs.aws.amazon.com/redshift/latest/dg/c_high_level_system_architecture.html

如果您打算使用紅移的RDBMS是一個值得努力閱讀以下還有:

http://docs.aws.amazon.com/redshift/latest/dg/c_redshift-and-postgres-sql.html

問題:

在Redshift的自動增量/序列/標識列中通過檢索最後插入的id的最佳策略是什麼PostgreSQL JDBC驅動程序?

回答

4

給出的紅移引擎是建立在PostgreSQL的8.0.2及以上回歸與是Statement.RETURN_GENERATED_KEYS選項不可 可用,紅移不支持的CREATE使用CURRVAL/NEXTVAL功能套件的序列,其中一個方案是到 將兩個SQL語句組合在一起,即JDBC事務中的INSERT和SELECT MAX([identity column])。

try { 

    // create the JDBC connection 
    Class.forName(JDBC_DRIVER); 
    Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD); 

    // start the transaction 
    conn.setAutoCommit(false); 
    // create the prepared statement for insert 
    PreparedStatement prpd = conn.prepareStatement(SQL_INSERT_STATEMENT); 

    // set input/output parameters as needed... 

    // execute the SQL prepared statement 
    int j = prpd.executeUpdate(); 

    // create a statement for select max() 
    Statement stmt = conn.createStatement(); 
    // execute the statement to return a result set   
    ResultSet key = stmt.executeQuery(SQL_SELECT_MAX_STATEMENT); 

    // initialize and retrieve the incremented identity value, in this case it is a long (bigint data type in Redshift) 
    long id = 0; 
    if (key.next()) { 
     id = key.getLong(1); 
    } 

    // commit the entire transaction   
    conn.commit(); 

} catch (SQLException se) { 
    // if an SQL exception occurs, rollback the whole deal 
    try { 
     if (conn!=null && !conn.isClosed()) { 
      conn.rollback(); 
     } 

    } catch (Exception e) { 

    } 
} catch (Exception e) { 
    // roll back if something other than an SQLException occurs 
    try { 
     if (conn!=null && !conn.isClosed()) { 
      conn.rollback(); 
     } 
    } catch (Exception e) { 

    } 
} finally { 
    // do whatever you want to return a value, shut down resources 
    // close out JDBC resources 
    try { 
     if (conn!=null && !conn.isClosed()) { 
      conn.setAutoCommit(true); 
     }     
    } catch (SQLException se) { 

    } 

    try {     
     if (prpd!=null && !prpd.isClosed()) { 
      prpd.close(); 
     }         
    } catch (SQLException se) { 

    } 

    try {     
     if (stmt!=null && !stmt.isClosed()) { 
      stmt.close(); 
     }         
    } catch (SQLException se) { 

    } 

    try { 
     if (conn!=null && !conn.isClosed()) { 
      conn.close(); 
     } 
    } catch (SQLException se) { 

    } 
} 

如果SQL_INSERT_STATEMENT寫入上面將工作/鎖定一個單一的表。多個表鎖需要同步關鍵字 以防止死鎖。在鎖定的表上選擇將允許在ResultSet中返回遞增的身份值爲 。