Одна проблема с ROWID заключается в том, что это 4-байтовая величина, но значение, используемое в фрагментированной таблице, представляет собой 8-байтовую величину (номинально FRAGID и ROWID), но Informix никогда не раскрывала FRAGID.
Теоретически структура данных SQLCA сообщает ROWID в элементе sqlca.sqlerrd[5]
(предполагается, что индексация в стиле 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# может получить доступ к DLL, написанным на C, вы можете упаковать это.
В противном случае утвержденным способом идентификации строк данных является использование первичного ключа (или любого другого уникального идентификатора, иногда называемого альтернативным ключом или ключом-кандидатом) для строки. Если у вас нет первичного ключа или другого уникального идентификатора строки, вы усложняете себе жизнь. Если это составной ключ, это «работает», но может быть неудобно. Возможно, вам нужно добавить в таблицу столбец SERIAL (или столбец BIGSERIAL).
Вы можете использовать:
SELECT ROWID
FROM TargetTable
WHERE PK_Column1 = <value1> AND PK_Column2 = <value2>
или что-то подобное для получения ROWID, если вы можете точно идентифицировать строку.
В крайнем случае существует механизм добавления физического столбца ROWID к фрагментированной таблице (обычно это виртуальный столбец). Затем вы должны использовать запрос выше. Это не рекомендуется, но вариант есть.
person
Jonathan Leffler
schedule
27.11.2010