如何在SQL Server 2012+上使用JdbcTemplate获取生成的序列ID

时间:2018-02-05 22:11:06

标签: sql-server spring-jdbc jdbctemplate

我在SQL Server 2012中有一个表,它使用Sequence来使用默认约束生成主键。

CREATE TABLE [vfm].[ChangeEvent](
    [ChangeEventId] [int] NOT NULL,
    [Description] [varchar](100) NOT NULL,
    [LegalEffectiveDate] [date] NOT NULL,
    [StatusCode] [char](1) NOT NULL,
 CONSTRAINT [PK_ChangeEvent] PRIMARY KEY CLUSTERED 
(
    [ChangeEventId] ASC
)

ALTER TABLE [vfm].[ChangeEvent] ADD  CONSTRAINT [DF_ChangeEvent_1]  DEFAULT 
(NEXT VALUE FOR [vfm].[SEQ_ChangeEventId]) FOR [ChangeEventId]

我在Spring 5.x中使用NamedParameterJdbcTemplate将新记录插入表中。

StringBuilder sql = new StringBuilder()
    .append("insert into vfm.ChangeEvent(Description, LegalEffectiveDate, StatusCode)")
    .append(" values (:description, :legalEffectiveDate, :status)");

SqlParameterSource parameters = new MapSqlParameterSource()
    .addValue("description", changeEvent.getDescription())
    .addValue("legalEffectiveDate", changeEvent.getLegalEffectiveDate())
    .addValue("status", "S");

KeyHolder keyHolder = new GeneratedKeyHolder();
namedParameterJdbcTemplate.update(sql.toString(), parameters, keyHolder, new String[] { "ChangeEventId" });

从我到目前为止看到的,我的KeyHolder返回空,GENERATED_KEYS = null。是否可以配置.update调用来检索生成的ChangeEventId?或者我因为表使用序列对象而被卡住了?

我相信这对Oracle来说是可行的,但我没有看到任何SQL Server的答案。我见过的SQL Server问题使用了标识列,而不是序列。

1 个答案:

答案 0 :(得分:1)

这是最终为我工作的东西。

  • 在SQL查询中使用output insert.<id>返回插入的值
  • queryForObject
  • 上使用update代替NamedParameterJdbcTemplate
  • 确保序列设置为列默认值
StringBuilder sql = new StringBuilder()
    .append("insert into vfm.ChangeEvent(Description, LegalEffectiveDate, StatusCode)")
    .append(" output inserted.ChangeEventId")
    .append(" values (:description, :legalEffectiveDate, :status)");

SqlParameterSource parameters = new MapSqlParameterSource()
    .addValue("description", changeEvent.getDescription())
    .addValue("legalEffectiveDate", changeEvent.getLegalEffectiveDate())
    .addValue("status", "S");

Integer changeEventId = namedParameterJdbcTemplate.queryForObject(sql.toString(), parameters, Integer.class);