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

How to fetch generated sequence ID using JdbcTemplate on SQL Server 2012+

我在 SQL Server 2012 中有一个 table,它使用 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 将新记录插入 table。

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?还是我卡住了,因为 table 使用的是序列对象?

我相信 Oracle 可以做到这一点,但我还没有看到 SQL 服务器的任何答案。 SQL 我见过的服务器问题使用的是标识列,而不是序列。

这是最终对我有用的东西。

  • 在 SQL 查询中使用 output insert.<id> 来 return 插入的值
  • NamedParameterJdbcTemplate
  • 上使用 queryForObject 而不是 update
  • 确保序列设置为默认列

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);