Informix:如何获取最后一个插入语句的 rowid
Posted
技术标签:
【中文标题】Informix:如何获取最后一个插入语句的 rowid【英文标题】:Informix: How to get the rowid of the last insert statement 【发布时间】:2010-11-24 19:42:45 【问题描述】:这是我之前提出的一个问题的延伸:C#: How do I get the ID number of the last row inserted using Informix
我正在用 C# 编写一些代码,以使用 .NET Informix 驱动程序将记录插入到 informix 数据库中。我能够获得最后一次插入的 id,但在我的一些表中,没有使用“串行”属性。我一直在寻找类似于以下的命令,但要获取 rowid 而不是 id。
SELECT DBINFO ('sqlca.sqlerrd1') FROM systables WHERE tabid = 1;
是的,我确实意识到使用 rowid 是危险的,因为它不是恒定的。但是,我计划让我的应用程序强制客户端应用程序重置数据,如果表格以重新排列的方式或类似的方式更改。
【问题讨论】:
你可以在 where 子句中使用最后一个插入 id 来选择 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 列添加到碎片表(通常是虚拟列)。然后,您将使用上面的查询。不建议这样做,但可以选择。
【讨论】:
如果我选择使用 C 代码,除了该代码之外还有什么我需要的吗?我知道 C# 可以使用 DllImport(...) 来调用非托管代码,但我想知道 C 代码是否需要引用它执行的 Informix 连接或 Informix 命令? @myermian:我不知道是简短的答案...您可能需要使用线程标志进行编译(esql -thread ... 在 Unix 上;在 Windows 上可能相同),以便将 sqlca 映射到返回指向 sqlca 结构的(线程特定的)指针的函数。但是,您可能不需要其他任何东西。它将在线程的上下文中调用,并且(应该)为您提供与您的线程关联的值。以上是关于Informix:如何获取最后一个插入语句的 rowid的主要内容,如果未能解决你的问题,请参考以下文章
Informix 数据库中的 Hibernate 批量插入(获取 sql 日志跟踪)
使用 prepare 语句在 informix 4gl 中创建临时表