Как получить информацию из поля, для которого свойство Required установлено как false?

В моем программном обеспечении используется следующая структура DBX:

TSQLDataSet -> TDataSetProvider -> TClientDataSet

В одном из полей моего TClientDataSet для свойства Required установлено значение false, потому что это поле автоматически увеличивается на основе триггеров и генераторов в базе данных (Firebird).

Однако после настройки как TSQLDataSet, так и TClientDataSet, когда это поле не требуется, я получаю действительно странные результаты, когда пытаюсь прочитать это поле из своего TClientDataSet. Я подозреваю, что мне может потребоваться что-то дополнительное, чтобы заставить мой TClientDataSet получить значение этого поля в этом состоянии.

Что мне здесь не хватает?

Заранее спасибо.

ИЗМЕНИТЬ

В файле справки для свойства Required что-то говорится об этом, но я не мог понять, что от меня требуется.

Описание

Указывает, требуется ли для поля непустое значение.

Используйте параметр «Обязательно», чтобы узнать, требуется ли для поля значение или оно может быть пустым.

Если поле создается с помощью редактора полей, это свойство устанавливается на основе базовой таблицы. Приложения, которые устанавливают для параметра Required значение true для полей, которые должны иметь значения (например, пароль или номер детали), но для которых базовая таблица не требует поля, должны написать обработчик событий OnValidate для принудительного применения свойства.

Когда свойство Required отражает свойство базовой таблицы базы данных, попытка публикации с применением нулевого значения вызывает исключение. Приложения, которые устанавливают для свойства Required значение true, когда для базовой таблицы поле не требуется, должны вызывать исключение EDatabaseError для значений NULL в обработчике событий OnValidate, чтобы добиться того же результата.

ИЗМЕНИТЬ 2

Забыл упомянуть: между TDataSetProvider и TClientDataSet есть слой DataSnap (соединение TClientDataSet осуществляется с помощью драйвера DataSnap).

ИЗМЕНИТЬ 3

Я создал небольшой тестовый пример с этой настройкой DataSnap, и он отлично сработал. Проект устаревший, беспорядочный, и я предполагаю, что либо у меня где-то настроена непонятная опция, которая меня кусает, либо я наткнулся на ошибку DataSnap.


person ivarec    schedule 27.01.2012    source источник
comment
Как вы пытаетесь прочитать поле из ClientDataSet? При чтении из поля не имеет значения, является ли поле обязательным или нет; он влияет только тогда, когда данные записываются в таблицу / набор данных при операции вставки или редактирования.   -  person Ken White    schedule 27.01.2012
comment
cds.FieldByName ('ПОЛЕ'). AsString; // проблема возникает только с полем Required: = false.   -  person ivarec    schedule 27.01.2012
comment
Какие странные результаты? У вас есть увеличивающееся поле String?   -  person Marcus Adams    schedule 28.01.2012
comment
Вы все еще не понимаете. Как сказал Маркус, каковы странные результаты? Чтение из поля не имеет ничего общего со свойством Required, и часть цитируемых вами документов полностью посвящена записи в данные (в последнем абзаце конкретно говорится о попытке публикации, а в абзаце перед этим упоминает наличие события OnValidate для принудительного применения необходимого свойства в ClientDataSet, когда базовая база данных не требует этого, что опять же связано с записью в поле).   -  person Ken White    schedule 28.01.2012
comment
@KenWhite Допустим, в моей таблице два поля: ИНДЕКС (целое число) и ИМЯ (varchar). Если моя текущая активная запись указывает на строку, имеющую в качестве значений (3, John), попытка прочитать ее с помощью процедуры, указанной ранее, дает мне (1953366016, John). Но это работает для первой записи (если бы это было (1, Мэри), я бы получил (1, Мэри)).   -  person ivarec    schedule 28.01.2012


Ответы (2)


Хаоле, вы пробовали TClientDataset.RefreshRecord после вставки? Или даже TClientDataset.Refresh? Имея генераторы, вы даже можете получить генератор заранее (перед вызовом ApplyUpdates) в запросе типа select gen_id(generator,1) from RDB$Database (это из памяти, здесь нет Firebird для тестирования) и заранее заполнить поле PK.

РЕДАКТИРОВАТЬ: кажется, это heisenbug. Я бы попытался удалить компоненты и перенастроить их снова с нуля (что означает: после удаления сохраните и закройте Delphi).

Или, что еще лучше, создайте пустой проект с необходимой конфигурацией запроса и попробуйте просмотреть эти данные в TDBGrid. Если эта проблема все еще возникает, возможно, в вашей установке FB поврежден какой-то компонент (или даже установка Delphi)

person Fabricio Araujo    schedule 27.01.2012
comment
Ну никаких прошивок пока не задействовано. У меня есть некоторые данные, которые уже есть в БД, и я не могу правильно прочитать это поле с помощью своего TClientDataSet. - person ivarec; 27.01.2012
comment
TClientDataset.Refresh не решает эту проблему. И получение такого значения генератора опасно, поскольку мое приложение является многопоточным. - person ivarec; 27.01.2012
comment
Хм. Простой SELECT на IBExpert или даже ISQL показывает правильные данные? - person Fabricio Araujo; 27.01.2012
comment
Вы изменили TField.Required как на TClientDataset, так и на TSQLDataset? - person Fabricio Araujo; 27.01.2012
comment
У меня здесь нет Firebird на моей машине, только на моем ноутбуке. Я попробую воспроизвести это. Помогло бы, если бы вы позволили нам узнать соответствующую структуру рассматриваемой таблицы. - person Fabricio Araujo; 27.01.2012
comment
haole: getting the generator value like that is dangerous, as my application is threaded - многопоточность не представляет угрозы для генераторов Firebird - person mjn; 27.01.2012
comment
@mjn: возможно, это опасно для приложения, поскольку этот конкретный генератор может использоваться для создания контрольного журнала (и не может иметь дыр) или заказа №. - person Fabricio Araujo; 27.01.2012

Похоже, проблема заключалась в том, что устаревшее поле читалось как INTEGER, а в базе данных было SMALLINT.

Эту проблему было трудно отладить, и этот вопрос вводил в заблуждение. Спасибо всем, кто помог мне отладить это.

person ivarec    schedule 30.01.2012