简体   繁体   English

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

[英]Informix: How to get the rowid of the last insert statement

This is an extension of a question I asked before: C#: How do I get the ID number of the last row inserted using Informix 这是我之前提出的问题的扩展: C#:如何获取使用Informix插入的最后一行的ID号

I am writing some code in C# to insert records into the informix db using the .NET Informix driver. 我正在用C#编写一些代码,以使用.NET Informix驱动程序将记录插入到notifyix数据库中。 I was able to get the id of the last insert, but in some of my tables the 'serial' attribute is not used. 我能够获取最后一次插入的ID,但是在某些表中未使用'serial'属性。 I was looking for a command similar to the following, but to get rowid instead of id. 我在寻找与以下类似的命令,但要获取rowid而不是id。

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

And yes, I do realize working with the rowid is dangerous because it is not constant. 是的,我的确意识到使用rowid很危险,因为它不是恒定的。 However, I plan to make my application force the client apps to reset the data if the table is altered in a way that the rowids got rearranged or the such. 但是,我计划让我的应用程序强制客户端应用程序,如果以重新排列rowid或类似方式更改表的方式来重置数据。

One problem with ROWID is that it is a 4-byte quantity but the value used on a fragmented table is an 8-byte quantity (nominally FRAGID and ROWID), but Informix has never exposed the FRAGID. ROWID的一个问题是它是4字节的数量,但在碎片表上使用的值是8字节的数量(名义上为FRAGID和ROWID),但是Informix从未公开过FRAGID。

In theory, the SQLCA data structure reports the ROWID in the sqlca.sqlerrd[5] element (assuming C-style indexing from 0; it is sqlca.sqlerrd[6] in Informix 4GL which indexes from 1). 从理论上讲,SQLCA数据结构在sqlca.sqlerrd[5]元素中报告ROWID(假定C风格的索引从0开始;在Informix 4GL中是sqlca.sqlerrd[6] ,从1开始进行索引)。 If anything was going to work with DBINFO, it would be DBINFO('sqlca.sqlerrd5') , but I get: 如果有什么要使用DBINFO,它将是DBINFO('sqlca.sqlerrd5') ,但是我得到:

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

So, the indirect approach using DBINFO is not on. 因此,使用DBINFO的间接方法未启用。 In ESQL/C, where sqlca is readily available, the information is available too: 在容易使用sqlca ESQL / C中,该信息也可用:

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]: 

I am not a user of C# or the .NET driver, so I have no knowledge of whether there is a back-door mechanism to get at the information. 我不是C#或.NET驱动程序的用户,所以我不知道是否有后门机制来获取信息。 Even in ODBC, there might not be a front-door mechanism to get at it, but you could drop into C code to read the global data structure easily enough: 即使在ODBC中,也可能没有前门机制可以实现,但是您可以加入C代码以足够容易地读取全局数据结构:

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

Or, even: 甚至:

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

If C# can access DLL's written in C, you could package that up. 如果C#可以访问用C编写的DLL,则可以将其打包。

Otherwise, the approved way of identifying rows of data is via the primary key (or any other unique identifier, sometimes known as an alternative key or candidate key) for the row. 否则,识别数据行的批准方法是通过该行的主键(或任何其他唯一标识符,有时称为替代键或候选键)。 If you don't have a primary key or other unique identifier for the row, you are making life difficult for yourself. 如果您没有该行的主键或其他唯一标识符,那么您将很难过自己的生活。 If it is a compound key, that 'works' but could be inconvenient. 如果它是复合键,则“有效”,但可能会带来不便。 Maybe you need to consider adding a SERIAL column (or BIGSERIAL column) to the table. 也许您需要考虑将SERIAL列(或BIGSERIAL列)添加到表中。

You can use: 您可以使用:

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

or something similar to obtain the ROWID, assuming you can identify the row accurately. 或类似的方法来获取ROWID,前提是您可以准确识别行。

In dire straights, there is a mechanism to add a physical ROWID column to a fragmented table (normally, it is a virtual column). 在困境中,有一种机制可以将物理ROWID列添加到碎片表中(通常是虚拟列)。 You'd then use the query above. 然后,您将使用上面的查询。 This is not recommended, but the option is there. 不建议这样做,但可以使用该选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM