Informix:如何获取最后一个insert语句的rowid

时间:2010-11-24 19:42:46

标签: c# sql informix lastinsertid rowid

这是我之前提出的问题的扩展:C#: How do I get the ID number of the last row inserted using Informix

我在C#中编写一些代码,使用.NET Informix驱动程序将记录插入informix数据库。我能够获得最后一个插入的id,但是在我的一些表中,没有使用'serial'属性。我正在寻找类似于以下的命令,但要获得rowid而不是id。

SELECT DBINFO ('sqlca.sqlerrd1') FROM systables WHERE tabid = 1;

是的,我确实意识到使用rowid是危险的,因为它不是恒定的。但是,我计划让我的应用程序强制客户端应用程序重置数据,如果表格被更改为rowid重新排列的方式或等等。

1 个答案:

答案 0 :(得分:1)

ROWID的一个问题是它是一个4字节的数量但是在碎片表上使用的值是8字节的数量(名义上是FRAGID和ROWID),但是Informix从未暴露过FRAGID。

理论上,SQLCA数据结构报告sqlca.sqlerrd[5]元素中的ROWID(假设C样式索引从0开始;它在Informix 4GL中为sqlca.sqlerrd[6],索引为1)。如果有任何东西可以用于DBINFO,它将是DBINFO('sqlca.sqlerrd5'),但我得到:

SQL -728: Unknown first argument of dbinfo(sqlca.sqlerrd5).

因此,使用DBINFO的间接方法尚未开启。在ESQL / C中,sqlca随时可用,信息也可用:

SQL[739]: begin;
BEGIN WORK: Rows processed = 0
SQL[740]: create table p(q integer);
CREATE TABLE: Rows processed = 0
SQL[741]: insert into p values(1);
INSERT:  Rows processed = 1, Last ROWID = 257
SQL[742]: select dbinfo('sqlca.sqlerrd5') from dual;
SQL -728: Unknown first argument of dbinfo(sqlca.sqlerrd5).
SQLSTATE: IX000 at /dev/stdin:4
SQL[743]: 

我不是C#或.NET驱动程序的用户,所以我不知道是否有后门机制来获取信息。即使在ODBC中,也可能没有前端机制来实现它,但您可以使用C代码轻松地读取全局数据结构:

#include <sqlca.h>
#include <ifxtypes.h>
int4 get_sqlca_sqlerrd5(void)
{
    return sqlca.sqlerrd[5];
}

或者,甚至:

int4 get_sqlca_sqlerrdN(int N)
{
    if (N >= 0 && N <= 5)
        return sqlca.sqlerrd[N];
    else
        return -22;  /* errno 22 (EINVAL): Invalid argument */
}

如果C#可以访问用C语言编写的DLL,你可以打包它。

否则,批准的识别数据行的方式是通过该行的主键(或任何其他唯一标识符,有时称为替代键或候选键)。如果您没有该行的主键或其他唯一标识符,那么您将使自己的生活变得困难。如果它是复合键,那“有效”但可能不方便。也许您需要考虑在表中添加SERIAL列(或BIGSERIAL列)。

您可以使用:

SELECT ROWID
  FROM TargetTable
 WHERE PK_Column1 = <value1> AND PK_Column2 = <value2>

或类似的东西,以获得ROWID,假设您可以准确识别行。

在直截了当中,有一种机制可以将物理ROWID列添加到碎片表(通常,它是一个虚拟列)。然后,您将使用上面的查询。不建议这样做,但选项就在那里。