这是我之前提出的问题的扩展: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重新排列的方式或等等。
答案 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列添加到碎片表(通常,它是一个虚拟列)。然后,您将使用上面的查询。不建议这样做,但选项就在那里。