Лена |
Отправлено: 05.10.2006, 10:57 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
В базе данных есть поле определенное как время:
stime time NOT NULL, записи в нем храниться в виде 10:00:00
Задала для поля маску __:__:__ пишу в нем без ошибок, например 18:00:00 и всегда получаю исключение на прилагаемом рисунке при попытке ApplyUpdates(-1).
Не совсем понятно, о чем это исключение говорит о каких-то временных зонах?
Обработчик OnSetText также не работает:
CODE |
void __fastcall TDataModule2::ClientDataSetRuleetimeSetText(TField *Sender,
const AnsiString Text)
{
try{
TDateTime dtDate = StrToTime(Text); // проверка на формат времени
ClientDataSetRuleetime->AsDateTime = dtDate;
}
catch(...)
{
ShowMessage("Введите правильно время");
//Abort();
}
}
|
Как, в моем случае, послать запись содержащую только время, в базу?
Отредактировано Лена — 05.10.2006, 11:00
Присоединить изображение
|
|
olegenty |
Отправлено: 05.10.2006, 11:47 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
для начала попробуй
и Ruleetime неплохо, чтобы было TTimeField
CODE |
try
{
TTime ttTime = StrToTime(Text); // проверка на формат времени
ClientDataSetRuleetime->AsDateTime = ttTime;
} catch(...)
{
ShowMessage("Введите правильно время");
//Abort();
}
|
|
|
Лена |
Отправлено: 05.10.2006, 12:30 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Исключение не пропало.
Что-то видимо с этой таблицей и ее связями в базе или еще что. Любое редактирование столбцов с любыми данными в них приводит к исключению при попытке ApplyUpdates(-1); В самой базе значения могу менять в этой таблице, а у себя в гриде после редактирования и перехода курсора на другую запись исключение. Я ничего не удаляю, просто например, меняю в колонке цифру и получаю это исключение.
В каком направлении искать ошибку?
Присоединить изображение
|
|
Admin |
Отправлено: 05.10.2006, 12:45 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
Так это уже другой вопрос, не связанный со временем ?
Со временем все исправилось ?
---
Может попробовать
UpdateMode = upWhereKeyOnly в TDataSetProvider
http://www.delphikingdom.com/asp/answer.as...?IDAnswer=28103
QUOTE |
Если в таблице есть ключевое поле, то необходимо указать его в SqlQuery (ProviderFlags = pfInKey), остальным полям убрать флаг pfInWhere. Провайдеру указать UpdateMode = upWhereKeyOnly. Если же ключевого поля нет, то придется "помучаться" с указанием полей, у которых ProviderFlags установить в pfInWhere. Никаким текстовым полям pfInWhere устанавливать нельзя. |
|
|
Лена |
Отправлено: 05.10.2006, 13:13 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
>Со временем все исправилось ?
Нет, не исправилось. Со временем сначала первое исключение на рисунке, потом второе. Рисунки выше. Если модифицировать запись в колонке, где просто цифры int то тогда просто второе исключение.
Спасибо за дополнительную информацию. Буду разбираться.
|
|
olegenty |
Отправлено: 05.10.2006, 13:16 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
с EhLib давно бы уже всё сделала.
|
|
Лена |
Отправлено: 05.10.2006, 13:17 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Попробывала: UpdateMode = upWhereKeyOnly в TDataSetProvider
пока исключение:
Присоединить изображение
|
|
Лена |
Отправлено: 05.10.2006, 13:19 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
>с EhLib давно бы уже всё сделала.
Не дают использовать другие компоненты.
Я уже пять таблиц оформила, почти закончила. Шестая таблица не поддается. Буду копать.
CREATE TABLE rights
(
id int4 NOT NULL DEFAULT nextval('rights_id_seq'::regclass),
gate_id int4 NOT NULL,
group_id int4 NOT NULL,
dweek int2 NOT NULL, -- день недели, 0 — воскр
stime time NOT NULL,
etime time NOT NULL,
CONSTRAINT rights_pk PRIMARY KEY (id)
)
WITHOUT OIDS;
ALTER TABLE rights OWNER TO postgres;
COMMENT ON COLUMN rights.dweek IS 'день недели, 0 — воскр';
Отредактировано Лена — 05.10.2006, 13:22 |
|
Admin |
Отправлено: 05.10.2006, 13:25 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
QUOTE | Попробывала: UpdateMode = upWhereKeyOnly в TDataSetProvider пока исключение |
Так еще определитесь с ключевыми полями в таблице, ключевому
полю в свойстве ProviderFlags: pfInKey = true,
остальным полям — pfInWhere = false (ну естественно им pfInKey = false)
P.S. Как раз это исключение и сообщает, что в таблице
не задано ключевое поле. Значит верной дорогой идем, товарищи.
Для указанной таблицы rights это получается поле id.
|
|
olegenty |
Отправлено: 05.10.2006, 13:29 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
а так?
CODE |
try
{
TTime ttTime = StrToTime(Text); // проверка на формат времени
ClientDataSetRuleetime->AsString = Text;
} catch(...)
{
ShowMessage("Введите правильно время");
//Abort();
}
|
|
|
Admin |
Отправлено: 05.10.2006, 13:38 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
QUOTE | >с EhLib давно бы уже всё сделала. |
Думаю, что с olegenty и Admin тоже всё получиться.
|
|
Лена |
Отправлено: 05.10.2006, 14:17 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
>Думаю, что с olegenty и Admin тоже всё получиться
>а так?
Не помогло. Меняю пару цифр, например в часах, щелкаю мышью на другой строке и как только доходит до ApplyUpdates(-1) (смотрю через точки останова), то получаю первое исключение с временными зонами. Наверное это связано с общей пробемой обновления этой таблицы.
>ProviderFlags: pfInKey = true,
Я могу добраться до этого свойства в редакторе полей ClientDataSet или ADOQuery. Где лучше установить это свойство или без разницы?
>Как раз это исключение и сообщает, что в таблице
не задано ключевое поле.
А разве эта запись в базе не создает ключевое поле: PRIMARY KEY (id) ?
Все таблицы вроде однородны по структуре. Почему-то проблема именно с этой при редактировании.
Почему эти манипуляции c ProviderFlags мне не потребовались с другими таблицами? Например с этой:
CREATE TABLE gates
(
id int4 NOT NULL DEFAULT nextval('gates_id_seq'::regclass),
name varchar(50) NOT NULL,
enabled bool NOT NULL,
CONSTRAINT pk_gates PRIMARY KEY (id)
)
WITHOUT OIDS;
ALTER TABLE gates OWNER TO postgres;
Может мне надо во всех таблицах установить ProviderFlags для ключевых полей?
|
|
Admin |
Отправлено: 05.10.2006, 14:43 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
QUOTE | Не помогло. Меняю пару цифр, например в часах, щелкаю мышью на другой строке и как только доходит до
......
получаю первое исключение с временными зонами. Наверное это связано с общей пробемой обновления этой таблицы.
|
Не думаю. Скорее не связано.
Тут надо смотреть, с какой строчки кода идет это исключение.
Может формат 00:00:00 в базе вовсе не означает
часы:минуты:секунды ?
Посмотрите ещё окно настроек соединения, там вроде есть еще
Page2, может тоже как формат времени задается ?
Может попробовать еще
так:
ClientDataSetRuleetime->Value = Text;
и так:
TTime ttTime = StrToTime(Text); // проверка на формат времени
ClientDataSetRuleetime->Value = ttTime;
и предварительно посмотрите,
1/ что в Text — например задав ShowMessage(Text); ?
2/ проверьте, какой тип поля имеет поле Ruleetime ?
QUOTE | Я могу добраться до этого свойства в редакторе полей ClientDataSet или ADOQuery. Где лучше установить это свойство или без разницы?
|
Честно говоря, не знаю. Попробуйте и там и там.
Но второе исключение должно исчезнуть.
|
|
Admin |
Отправлено: 05.10.2006, 14:58 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
И какой SQL-запрос изменения значений в таблице ?
(ADOQuery делает только Select, а каким образом идет
изменение данных Update — код ?)
Может в этом SQL-запросе какая-то бяка связанная с этим полем ?
Select CAST(stime as time) from ...
|
|
Admin |
Отправлено: 05.10.2006, 15:22 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
Поскольку c PostgreSQL не знаком:
Может реально в базе данные типа time хранятся в формате 000000,
а двоеточия показываются лишь при отображении данных ?
Может тогда так:
CODE |
try
{
TTime ttTime = StrToTime(Text); // проверка на формат времени
AnsiString s = Text;
s.Delete(s.Pos(":"),1); s.Delete(s.Pos(":"),1);
ClientDataSetRuleetime->AsString = s;
или
ClientDataSetRuleetime->AsDateTime = s;
}...
|
|
|
Лена |
Отправлено: 05.10.2006, 15:52 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Спасибо.
Исключение номер два пропало. Можно в двух словах объяснить, почему манипуляции с ProviderFlags необходимы были в этой таблице? Почему я не устанавливала это свойство для других таблиц и там все работало?
Осталось проблема с редактированием времени.
Для всех таблиц у меня просто в ADOQuery записано select * from таблица. Других SQL запросов нет. Обновление записано так:
void __fastcall TDataModule2::ClientDataSetRuleAfterPost(TDataSet *DataSet)
{
ClientDataSetRule->ApplyUpdates(-1);
}
Поле имеет тип TTimeField (вижу в инспекторе объектов).
В точке останова вижу, что строка ClientDataSetRuleetime->Value = Text равна 19:12:00
Строка TTime ttTime = StrToTime(Text); возвращает {val: 0.8}, а исключение возникает в событии:
void __fastcall TDataModule2::ClientDataSetRuleAfterPost(TDataSet *DataSet)
{
ClientDataSetRule->ApplyUpdates(-1);
}
Если убрать обработчик OnSetText, то исключение не происходит, а запись в гриде просто возвращается в исходный вид с потерей редактирования.
Посмотрела историю ошибок на сервере. Происходит какой-то глюк при передачи данных в колонку времени. Я передаю 19:12:00 а на сервер приходит в формате даты. Администратор сервера посмотрел, но пока не разобрался, почему так происходит. Что-то с типом time в PostgreSQL. Будем разбираться.
P.S.
Без двоеточий пишет "191200 not valid time"
|
|
olegenty |
Отправлено: 05.10.2006, 15:59 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
скорее проблема в драйвере, посредством которого доступаешься. либо во взаимодействии компонентов с этим драйвером.
|
|
Admin |
Отправлено: 05.10.2006, 16:29 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
QUOTE | Можно в двух словах объяснить, почему манипуляции с ProviderFlags необходимы были в этой таблице? Почему я не устанавливала это свойство для других таблиц и там все работало?
|
Встроенный help — F1 на ProviderFlags.
или http://www.megalib.com/books/7/MIDASBasics.htm
---
Проблемы со временем — по-видимому как и с полем bool — от базы.
Этот код нормально работает на том-же RxMemoryData
CODE |
//---------------------------------------------------------------------------
void __fastcall TForm1::MemRuleetimeSetText(TField *Sender, const AnsiString Text)
{
try{
TTime ttTime = StrToTime(Text);
MemRuleetime->AsDateTime = ttTime;
}catch(...){
ShowMessage("Неверное врeмя !");
}
}
//---------------------------------------------------------------------------
|
Попробуйте вообще убрать все из EditMask этого поля и ввести
значение вручную типа: 10:00:00 , может в EditMask что-то лишнее ?
Если нет — значит скорее всего — база.
|
|
Admin |
Отправлено: 05.10.2006, 16:51 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
Попробуйте еще в OnSetText поля Ruleetime написать:
1. ClientDataSetRuleetime->AsString = "10:05:15";
если не заработает, то такой вариант:
2. ClientDataSetRuleetime->AsString = "'10:05:15'";
|
|
Лена |
Отправлено: 05.10.2006, 17:15 |
|
Мастер участка
Группа: Участник
Сообщений: 501
|
Все перепробовала, не выходит.
Когда выйдет, разработчик этой базы, на работу спрошу у него, может просто поменять тип поля в базе и все будет нормально.
Спасибо за помощь!
|
|