2013-04-02 51 views
2

嗨我在Postgres中有一個表,比如email_messages。它是分區的,所以無論使用我的java應用程序進行插入操作,都不會影響主表,因爲數據實際上正在插入到子表中。這是問題,我想獲得一個自動生成的列值(比如email_message_id,它是一個很大的串行類型)。 Postgres將它返回爲null,因爲在主表上沒有插入操作。對於oracle,我使用GeneratedKeyHolder來獲取該值。但我無法對postgres中的分區表執行相同的操作。請幫助我。在分區表中插入時獲取生成的鍵值

下面是我們用於甲骨文

public void createAndFetchPKImpl(final Entity pEntity, 
    final String pStatementId, final String pPKColumnName) { 


final SqlParameterSource parameterSource = 
    new BeanPropertySqlParameterSource(pEntity); 

    final String[] columnNames = new String[]{"email_message_id"}; 
    final KeyHolder keyHolder = new GeneratedKeyHolder(); 
    final int numberOfRowsEffected = mNamedParameterJdbcTemplate.update(
     getStatement(pStatementId), parameterSource, keyHolder, columnNames); 
    pEntity.setId(ConversionUtil.getLongValue(keyHolder.getKey())); 

} 
+0

「GeneratedKeyHolder」意味着你可能使用Spring,但我們不應該有猜測。詳情請。 JDBC驅動程序版本,任何更高級別的抽象如JPA/Spring,您的映射代碼等。 –

+0

是的,我們使用的是spring-jdbc版本3.1.1。 Postgres版本是8.1 –

+0

即使在表中發生插入操作,我也會將numberOfRowsEffected作爲零和keyHolder.getKey()作爲null。 –

回答

2

當您使用基於觸發器的分區中的PostgreSQL是JDBC驅動程序的報告,零行受到影響/插入正常的代碼片段。這是因爲原始SQL UPDATEINSERTDELETE實際上沒有生效,主表上沒有更改行。相反,操作是在一個或多個子表上執行的。

基本上,在PostgreSQL中的分區有點破解,這是它的一個更明顯的限制。

的解決方法是:

  • INSERT/UPDATE/DELETE直接抵靠所述子表(一個或多個),而不是頂級表;
  • 忽略結果rowcount;或
  • 使用 RULE S和 INSERT ... RETURNING代替(但他們有自己的問題) (不會對分區工作)
+0

我嘗試插入使用「RETURNING currval('email_messages_email_message_id_seq')」但仍然無法獲得該值。不過,我可以通過使用插入存儲過程來實現它。您能否指定我可以如何使用返回子句獲得該值 –

+0

@ user1495565您是使用基於規則的還是基於觸發器的分區? –

+0

如果我使用規則而不是觸發器(當前代碼)更改我的分區,按照postgres當前實現,它只允許無條件的INSTEAD規則包含RETURNING;此外,同一事件的所有規則中最多隻能有一個RETURNING子句。所以我無法從所有規則中返回值,因爲我對同一個表有多個分區。 –

相關問題