0

我正在尝试使用 Spring Jdbc Prepared 语句将记录插入表中。此代码必须在 Postgres 和 Oracle 上运行。插入后我需要读取插入的记录键。

我在 Spring 文档 JDBC 章节中找到了以下代码,上面写着“这适用于 Oracle”。
请参阅此处的链接(第 12.2.8 节)。

它可以很好地在 Postgres 上运行,插入记录,我可以使用 keyHolder 读取插入的记录键。但是在 Oracle 上它失败并显示以下错误消息...

[junit] STDOUT [ERROR] [2011.11.04 01:26:04] ..... - 测试......失败。[junit] 消息:PreparedStatementCallback;SQL []; ORA-01400: 无法将 NULL 插入 ("SOME_USER"."SOME_TABLE"."ID") [junit] ;嵌套异常是 java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("SOME_USER"."SOME_TABLE"."ID")

这是代码...

        KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(new PreparedStatementCreator()
    {
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException
        {
            PreparedStatement ps = connection.prepareStatement("insert into some_table(xxx_name,xxx_date), new String[] { "id" });
            ps.setString(1, "some name");
            ps.setDate(2, "some date");
            return ps;
        }
    }, keyHolder);

注意:我使用的是ojdbc6.jar(Oracle jdbc jar),commons dbcp jar

这是 applicationContext 数据源 bean

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.username}" />
    <property name="password" value="${db.password}" />
</bean>

对于表,我在 Postgres 和 Oracle 上都有序列some_table_id_seq。我必须使此代码适用于 Postgres(在开发机器上运行)和 Oracle(在生产上运行)。任何帮助/想法表示赞赏。谢谢你。

4

1 回答 1

2

您没有向我们展示 Postgres 和 Oracle 的表定义 (DDL),但我猜 ID 列是serial在 Postgres 中定义的,因此会自动从链接到该列的序列中检索一个新 ID

Oracle 没有这样的概念。如果您不想sequence.nextval手动调用(Postgres 也可以),您必须创建一个触发器,为该列分配下一个序列值。

CREATE OR REPLACE TRIGGER trg_ins_some_table
  BEFORE INSERT ON some_table
  FOR EACH ROW
BEGIN
   :new.id := some_table_id_seq.nextval;
END;
/
于 2011-11-05T08:18:58.233 回答