Firebird / IBPP вставляют молча

У меня есть приложение C ++, которое использует встроенную базу данных Firebird (например, использует fbembed.dll в Windows для встроенного использования) через библиотеку IBPP. В настоящее время я использую версию 2.5.3 Firebird и 2.5.3.1 IBPP. Проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь вставить данные, которые не могут быть вставлены из-за проблем с размером столбца или нарушения ограничений (например, вставка должна произойти сбой), я не получаю ошибки или указания, что вставка не удалась.

В качестве (упрощенного, но представительного) примера, у меня есть таблица типа:

create table USER_TABLE (
ID BIGINT not null,
USER_ID VARCHAR(10) not null,
DISPLAY_NAME VARCHAR(50) not null,
-- etc...
primary key (ID),
unique (USER_ID)
);

Столбец ID заполняется генератором в триггере перед вставкой. Теперь я пытаюсь вставить из моего приложения следующий код:

const string SQL_STMT = "insert into USER_TABLE ""(USER_ID, DISPLAY_NAME, etc) ""values (?, ?, ?);";
IBPP::Statement stmt = IBPP::StatementFactory(m_db, m_tr, SQL_STMT);
stmt->Set(1, userDataObject.getUserId());//returns const string&,
stmt->Set(2, userDataObject.getDisplayName());//returns const string&
//etc, etc...
stmt->Execute();

Если мой userDataObject.getUserId() значение слишком длинное для столбца 1234567890xxx Я не получу исключения, как я ожидал. Я могу (очевидно, успешно) получить идентификатор внутри той же транзакции с select ID from user_table where ... после выполнения вставки или через ... returning ID в конце SQL_STMT переменная выше. Но как только транзакция зафиксирована и другие части кода пытаются получить значения в таблице, ее там нет. Ни в коем случае я не получаю ошибку / исключение.

Есть идеи, почему я не получаю ошибку в этих обстоятельствах?

2

Решение

Итак, несколько недель спустя мы с коллегой наткнулись на причину этой проблемы, глядя на немного другую проблему. Мы выполняли нашу работу / тестирование с использованием 64-битной цепочки инструментов Microsoft Visual Studio C ++. Библиотеки Firebird возвращают информацию о состоянии и ошибках через массив типа ISC_STATUS, Библиотеки определяют это как typedef intptr_t размер указателя и, следовательно, в 64-битной системе равен 64 битам.

Библиотека IBPP динамически загружает клиентские библиотеки Firebird. Когда он определяет свою версию ISC_STATUS, он определяет это как long, В Linux / GCC я думаю, что это работает (например, будет 32 бита в 32-битной архитектуре и 64-битной в 64-битной архитектуре), но в Microsoft Visual C ++ long всегда 32 бита. В результате, когда мы скомпилировали и запустили 64-битную конфигурацию, она интерпретировала массив 64-битных целых как массив 32-битных целых. Результатом было то, что, поскольку все значения, которые были помещены в массив, были положительными целыми числами, которые помещаются в 32 бита, оказалось, что каждое другое значение в массиве состояния было 0. IBPP обнаруживает ошибки, проверяя ненулевое значение в из-за этого второе место в массиве, которое при 64-битной обработке всегда будет равно нулю.

Решением было обновить определение IBPP ISC_STATUS чтобы правильно соответствовать используемой клиентской библиотеке Firebird (это находится в заголовочном файле ‘ibase.h’).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]