1

这是我之前提出的一个问题的扩展:C#:如何获取使用 Informix 插入的最后一行的 ID 号

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

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

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

4

1 回答 1

1

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

理论上,SQLCA 数据结构报告sqlca.sqlerrd[5]元素中的 ROWID(假设 C 风格的索引从 0 开始;它sqlca.sqlerrd[6]在 Informix 4GL 中从 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 列添加到碎片表(通常是虚拟列)。然后,您将使用上面的查询。不建议这样做,但可以选择。

于 2010-11-27T15:29:06.867 回答