Новый триал IBProvider v3.50.0.28072
На сайт IBProvider загружен новый триал OLE DB провайдера — v3.50.0.28072, в котором исправлена структурная ошибка внутреннего представления данных из за которой были специфические затруднения с модификацией базы данных.
Суть проблемы заключалась в том, что провайдер не умел корректно обрабатывать DEFAULT-значения (они обрабатывались как NULL-значения). Для этого нужно было вместо пары {value, IsNull} работать с парой {value, Status}.
В новой сборке это досадное ограничение устранено и теперь IBProvider умеет передавать состояние данных через все свои слои — от верхнего до нижнего.
В самом низу с DEFAULT-значениями умеет работать только Firebird 2.5+ (и то очень ограничено). В FB2.5 появилась поддержка запроса:
INSERT INTO ... DEFAULT VALUES
Вот этот запрос теперь и используется при добавлении новых записей в «обновляемых» множествах.
На примере работы с провайдером через связанных сервер MSSQL это выглядит так:
Есть таблица TEST_MODIFY_ROW_WD, в которой для всех колонок (кроме первичного ключа) заданы DEFAULT-значения:
CREATE TABLE TEST_MODIFY_ROW_WD ( TEST_ID T_TEST_ID NOT NULL /* T_TEST_ID = BIGINT */, COL_SMALLINT T_SMALLINT DEFAULT 2 /* T_SMALLINT = SMALLINT */, COL_INTEGER T_INTEGER DEFAULT 4 /* T_INTEGER = INTEGER */, COL_DOUBLE T_DOUBLE DEFAULT 8.5 /* T_DOUBLE = DOUBLE PRECISION */, COL_FLOAT T_FLOAT DEFAULT 4.5 /* T_FLOAT = FLOAT */, COL_N_18_0 NUMERIC(18,0) DEFAULT 12345678901234567, COL_BIGINT T_BIGINT DEFAULT -12345678901234567 /* T_BIGINT = BIGINT */, COL_CHAR_10 T_CHAR_10 DEFAULT ' ABCD54321' /* T_CHAR_10 = CHAR(10) */, COL_CHAR_32 T_CHAR_32 DEFAULT ' 9876543210987654321' /* T_CHAR_32 = CHAR(32) */, COL_VARCHAR_10 T_VARCHAR_10 DEFAULT ' 10 ' /* T_VARCHAR_10 = VARCHAR(10) */, COL_VARCHAR_32 T_VARCHAR_32 DEFAULT ' COL_VARCHAR_32 ' /* T_VARCHAR_32 = VARCHAR(32) */, COL_NUM_2_1 NUMERIC(2,1) DEFAULT 2.1, COL_NUM_6_1 NUMERIC(6,1) DEFAULT 65432.1, COL_NUM_15_1 NUMERIC(15,1) DEFAULT 12345012345678.9, COL_TIMESTAMP T_TIMESTAMP DEFAULT '2018-03-21 11:25:03.1234' /* T_TIMESTAMP = TIMESTAMP */, COL_TYPE_DATE T_TYPE_DATE DEFAULT '2018-03-18' /* T_TYPE_DATE = DATE */, COL_TYPE_TIME T_TYPE_TIME DEFAULT '21:35:43.4321' /* T_TYPE_TIME = TIME */, COL_BOOLEAN T_BOOLEAN DEFAULT TRUE /* T_BOOLEAN = BOOLEAN */, COL_BYTES_BLOB T_BYTES_128 DEFAULT '1234' /* T_BYTES_128 = BLOB SUB_TYPE 0 SEGMENT SIZE 128 */, COL_TEXT_BLOB T_TEXT_128 DEFAULT ' qwerty ' /* T_TEXT_128 = BLOB SUB_TYPE 1 SEGMENT SIZE 128 */ );
Если добавлять записи через предыдущие выпуски провайдера, то в колонки COL_xxx будет установлен NULL:
Новый провайдер отработает этот запрос корректно:
На этом вся поддержка и заканчивается. К сожалению, в Firebird этот вопрос не дожат и в нем нет поддержки запроса «UPDATE … SET FIELD=DEFAULT» и параметров с DEFAULT-состояниями.
Вот так всегда — только ты начнешь делать по-настоящему интересные вещи …
Другие изменения в v3.50
1. При работе с обновляемыми множествами, если вы попытаетесь прочитать значения колонок, значения которых не были указаны или были установлены как DEFAULT, провайдер вернет ошибку и статусы DBSTATUS_E_UNAVAILABLE. Здесь еще нужно дорабатывать провайдер — задействовать «INSERT … RETURNING VALUES», «UPDATE … RETURNING VALUES». Задел для этого уже был сделан, дело за «малым».
2. Что-то мне захотелось закрутить гайки в отношении свойства инициализации «named_param_prefix«. Если раньше в него можно было устанавливать что угодно, то теперь разрешены только три значения — пустая строка, стандартный префикс «:» и префикс в стиле MSSQL «@». Никаких пробелов и прочих извращений. Только эти три значения.
В целом
Шкала удовлетворенности состоянием IBProvider вернулась к 90%. Я эту штуку с DEFAULT вынашивал около семи лет. Последний раз пытался её осилить в октябре 2014 и не смог — слишком большой объем изменений и отсутствовало четкое осознание проблемы. Поэтому я тогда переключился на более актуальные вещи 🙂
hvlad on 24 марта, 2018
> Суть проблемы заключалась в том, что провайдер не умел корректно обрабатывать DEFAULT-значения (они обрабатывались как NULL-значения). Для этого нужно было вместо пары {value, IsNull} работать с парой {value, Status}.
Насколько я помню, ADO (и, наверное OLEDB) прекрасно понимало значение Empty (Unassigned в Delphi) как маркер значения по-умолчанию.
> К сожалению, в Firebird этот вопрос не дожат и в нем нет поддержки запроса «UPDATE … SET FIELD=DEFAULT»
Есть в FB4.
> и параметров с DEFAULT-состояниями.
Это не делали. Уже не помню — почему 🙁