Informix: как получить идентификатор строки последнего оператора вставки - PullRequest
1 голос
/ 24 ноября 2010

Это расширение вопроса, который я задавал ранее: C #: Как получить идентификационный номер последней строки, вставленной с использованием Informix

Я пишу некоторый код на C # длявставьте записи в базу данных informix с помощью драйвера .NET Informix.Мне удалось получить идентификатор последней вставки, но в некоторых из моих таблиц атрибут «серийный» не используется.Я искал команду, похожую на следующую, но чтобы получить rowid вместо id.

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

И да, я понимаю, что работать с rowid опасно, потому что это не так.постоянная.Однако я планирую заставить свое приложение принудительно устанавливать клиентские приложения для сброса данных, если таблица изменена таким образом, что перестроены строки и т. Д.

1 Ответ

1 голос
/ 27 ноября 2010

Одна проблема с ROWID состоит в том, что это 4-байтовое количество, но значение, используемое во фрагментированной таблице, является 8-байтовым количеством (номинально FRAGID и ROWID), но Informix никогда не выставлял FRAGID.

Теоретически, структура данных SQLCA сообщает ROWID в элементе sqlca.sqlerrd[5] (при условии индексации в стиле 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 # может получить доступ к DLL, написанным на C, вы можете упаковать это.

В противном случае, одобренный способ идентификации строк данных - через первичный ключ (или любой другой уникальный идентификатор, иногдаизвестный как альтернативный ключ или ключ-кандидат) для строки.Если у вас нет первичного ключа или другого уникального идентификатора строки, вы усложняете себе жизнь.Если это составной ключ, это «работает», но может быть неудобно.Возможно, вам нужно добавить в таблицу столбец SERIAL (или столбец BIGSERIAL).

Вы можете использовать:

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

или что-то подобное для получения ROWID, при условии, что вы можете определитьстрока точно.

В тяжелых прямых есть механизм для добавления физического столбца ROWID к фрагментированной таблице (обычно это виртуальный столбец).Затем вы использовали бы запрос выше.Это не рекомендуется, но опция есть.

...