Во-первых, обратите внимание, что если ваша таблица фрагментирована, у нее не будет ROWID - если вы не создали ее с помощью предложения WITH ROWIDS, и в этом случае ROWID становится индексированным физическим столбцом вместо виртуального столбца.
Во-вторых, почему бы вам просто не использовать объявленный первичный ключ для таблицы вместо того, чтобы копаться за кулисами - особенно, когда версия копания за кулисами не работает.
Мне не ясно, почему используемая вами явная запись не выполняется так, как вы запрашиваете; это может быть драйвер JDBC, который сует свой нос туда, где его нос не принадлежит. Сколько столбцов вы получите в наборе результатов? Если это не выбранное вами число (количество столбцов в таблице плюс один), значит, что-то очень подозрительно.
Если бы мне нужно было посмотреть, что драйвер JDBC отправляет на сервер, я бы включил трассировку отладки SQLI - либо на стороне клиента, либо, если клиентская сторона не взаимодействует, на стороне сервера. В обычных (на основе C) API-интерфейсах для включения отладки SQLI необходимо задать переменную среды:
SQLIDEBUG=2:sqli
Это создаст файл с именем, начинающимся с 'sqli_
' в текущем каталоге процесса, выполняющего C API (ESQL / C, ODBC и т. Д.). Я предполагаю, что тот же механизм должен работать с драйвером JDBC.
Если SQLIDEBUG не работает с JDBC, то у вас гораздо более сложная работа - вам нужно включить отладку SQLI на стороне сервера.
Предполагая, что вы перехватываете выходные данные SQLI (интерфейса SQL), вы можете распечатать их, используя 'sqliprint
'. Вы бы искали SQL, отправленный в IDS. Если он не содержит ROWID, вы можете быть уверены, что драйвер JDBC играет с вами в глупые игры. Однако неясно, что бы вы сделали, чтобы обойти это. Может быть, использовать псевдоним таблицы (например, 't') и:
SELECT t.ROWID, t.* FROM WhateverTable t WHERE ...
Если выяснится, что JDBC настраивает ROWID, мы могли бы также попытаться использовать псевдоним:
SELECT ROWID AS pk_column, t.* FROM WhateverTable AS t WHERE ...
(AS является необязательным после имени таблицы.)
Пожалуйста, держите нас в курсе, если вы обнаружите что-нибудь интересное или полезное.
База данных уже установлена в нескольких местах и содержит скомпилированные приложения (для которых источник недоступен), которые могут сломаться при изменении схемы базы данных, поэтому я не могу добавить допустимые первичные ключи. Эти приложения используют rowid в качестве первичного ключа.
OK; это проектное решение, которое должно быть рассмотрено при вашем следующем основном обновлении , если у кого-либо из ваших клиентов достаточно большие объемы данных, чтобы фрагментация могла быть полезной. Помните, что фрагментированные таблицы не имеют виртуального столбца ROWID; их можно создать с помощью физического столбца ROWID, используя предложение WITH ROWIDS в операторах CREATE TABLE или ALTER FRAGMENT.
Используя log4jdbc, я смог подтвердить, что запрос, отправляемый в Informix, включает в себя запрос на rowid. Возвращается значение, и драйвер JDBC преобразует каждый столбец в ResultSet; Я вижу, что это приведение столбца rowid (ResultSet.getLong ()). Возвращенный объект ActiveRecord, однако, не включает значение rowid. Я полагаю, что это происходит потому, что когда у драйвера JDBC запрашивается схема таблицы, которая используется для определения доступных свойств класса ActiveRecord, rowid не возвращается. Любой вклад приветствуется ...
Хорошо сделано при получении информации. Неожиданно мои знания о том, что может делать драйвер JDBC, истощаются - это может быть чем-то, что нужно обратиться в службу технической поддержки IBM / Informix. У меня возникают различные вопросы - и я даже не уверен, что проблема в драйвере JDBC, дизайне JDBC в целом или в чем-то выше JDBC; Я ни в коем случае не являюсь экспертом в этой области. (Я могу произносить Java - C; это правильно?)
Вы пытались указать ROWID в последнем столбце оператора?
SELECT *, ROWID FROM WhereEver
А как насчет этого?
SELECT *, ROWID AS T_RowID FROM WhereEver
Если драйвер JDBC видит и то, и другое, значит, он работает слишком усердно и наносит вред всем. На самом деле, я даже не уверен, что знаю, как это работает с представлениями.
У меня есть таблица элементов:
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL UNIQUE CONSTRAINT c1_elements
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE CONSTRAINT c2_elements,
name CHAR(20) NOT NULL UNIQUE CONSTRAINT c3_elements,
atomic_weight DECIMAL(8,4) NOT NULL,
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
INSERT INTO elements VALUES( 1, 'H', 'Hydrogen', 1.0079, 'Y');
Мне удалось создать представление для этой таблицы, включая ROWID, и затем запросить ее:
CREATE VIEW x_elements(atomic_number, symbol, name, x_rowid)
AS SELECT atomic_number, symbol, name, ROWID AS x_rowid
FROM elements;
SELECT * FROM x_elements WHERE x_rowid < 512;
SELECT * FROM x_elements WHERE x_rowid >= 512;
Два запроса создали несвязанные наборы данных. Вы можете найти свою систему, чтобы использовать это. При необходимости вы должны переименовать базовые таблицы (например, «WhwhatTable» становится «Base_Whwhat»), а затем создать представление «WhwhatTable», чтобы выбрать данные из Base_Wh независимо от ROWID. Я формально не пробовал это с программой JDBC, но она «должна» работать (но поскольку исходный запрос также «должен» работать, я не уверен, насколько сильно я бы полагался на утверждение «должно работать»). ).