Firebird / IBPP:如何检索数据库自动增量生成的ID?

时间:2015-04-10 08:47:54

标签: c++ sql firebird

我将firebird数据库配置为自动增加表的主键。

CREATE GENERATOR GEN_CHANNEL_PARAMETER_SET_ID;
SET GENERATOR GEN_CHANNEL_PARAMETER_SET_ID TO 0;

CREATE TRIGGER CHANNEL_PARAMETER_SETS_BI FOR CHANNEL_PARAMETER_SETS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
    if (NEW.CHANNEL_PARAMETER_SET_ID is NULL) then NEW.CHANNEL_PARAMETER_SET_ID = GEN_ID(GEN_CHANNEL_PARAMETER_SET_ID, 1);
END

现在,在我使用IBPP的C ++程序中,我遇到了以下问题:

将数据集插入此表的新行时,我知道我的C ++程序中的所有值都会释放新的主键,因为数据库会创建它。如何从数据库中检索此密钥?

也许其他人也插入了一个条目 - 就在我插入一个条目后的那一刻。因此,检索具有最高值的PK可能会产生错误。我怎么处理这个?


采用Amir Rahimi Farahani的回答我找到了以下问题的解决方案:

我使用发电机:

CREATE GENERATOR GEN_CHANNEL_PARAMETER_SET_ID;
SET GENERATOR GEN_CHANNEL_PARAMETER_SET_ID TO 0;

以及以下C ++ / IBPP / SQL代码:

// SQL statement
m_DbStatement->Execute(
    "SELECT NEXT VALUE FOR gen_channel_parameter_set_id FROM rdb$database"
    );

// Retrieve Data
IBPP::Row ibppRow;
int64_t channelParameterSetId;

m_DbStatement->Fetch(ibppRow);
ibppRow->Get (1, channelParameterSetId);


// SQL statement
m_DbStatement->Prepare(
    "INSERT INTO channel_parameter_sets "
    "(channel_parameter_set_id, ...) "
    "VALUES (?, ...) " 
    );      

// Set variables
m_DbStatement->Set (1, channelParameterSetId);
...
...

// Execute
m_DbStatement->Execute ();
m_DbTransaction->CommitRetain ();

2 个答案:

答案 0 :(得分:4)

在插入新记录之前,可以生成并使用新的id:

SELECT NEXT VALUE FOR GEN_CHANNEL_PARAMETER_SET_ID FROM rdb$database

您现在知道新主键的值。

<强>更新
IBPP也支持RETURNING

// SQL statement
m_DbStatement->Prepare(
    "INSERT INTO channel_parameter_sets "
    "(...) VALUES (...) RETURNING channel_parameter_set_id" 
    );      

// Execute
m_DbStatement->Execute ();
m_DbTransaction->CommitRetain ();

// Get the generated id
m_DbStatement->Get (1, channelParameterSetId);
...

答案 1 :(得分:3)

要检索生成的密钥(或任何其他列)的值,您可以使用INSERT ... RETURNING ...

例如:

INSERT INTO myTable (x, y, z) VALUES (1, 2, 3) RETURNING ID

许多驱动程序还提供额外的功能来支持RETURNING,但我不了解IBPP。

请注意,从驱动程序的角度来看,使用RETURNING会使插入行为像可执行存储过程一样;某些驱动程序可能要求您以特定方式执行它。