| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Базы данных и репортинг > Update поля с датой типа DateTime |
| Автор: lenyska 18.3.2006, 17:33 |
| У меня БД в SQL Server, а приложение в Delphi. Для доступа пользуюсь компанентами ADO. При попытке сделать Update поля с датой типа DateTime выдается ошибка: Дополнительная возможность не реализованна. Код: ADOQuery8.Close; ADOQuery8.SQL.Clear; ADOQuery8.SQL.Add('update znakomue set day_rojd= ADOQuery8.Parameters [0].Value := Edit1.Text ; ADOQuery8.ExecSQL; Помогите, пожалуйста. Подскажите, где я ошибаюсь. Заранее спасибо!!! |
| Автор: Vit 18.3.2006, 19:03 | ||||
Но лучше дату передавать как дату, это позволит избежать проблем если национальные установки клиента и сервера разные:
|
| Автор: lenyska 18.3.2006, 21:12 |
| он все равно пишет ошибку: Project1.exe raised exception class EConverError with message "a ' is not a valid date and time'.Process stopped. независимо от того как вводишь дату: с помощью точек, слешей или запятых. HELP ME, PLEASE |
| Автор: Vit 19.3.2006, 16:36 | ||
| По видимому в моём коде такую ошибку может генерить только StrToDateTime, каклй у вас формат даты установлен на компьютере? Попробуйте выполнить следующую строку: Showmessage(datetimetostr(now)) и посмотрите на то в каком формате будет выведена дата, в таком же формате попробуйте ввести её в edit. Кроме того хотелось бы знать в каком именно месте происходит ошибка, видоизмените код:
|
| Автор: lenyska 19.3.2006, 19:21 |
| У меня формат даты: дд.мм.гггг Изменила код на предложенный вами, но все равно вылетает та же ошибка: Project1.exe raised exception class EConverError with message "a ' is not a valid date and time'.Process stopped. Что еще можно попробывать? |
| Автор: lenyska 20.3.2006, 19:36 |
| У меня третий вариант. Выскакивает ошибка: Error executing query [Microsoft][ODBC SQL Server Driver] Дополнительная возможность не реализованна Собственно, это тоже самое, что у меня было вначале. Это хорошо или плохо? И что с этим вообще делать? |
| Автор: Vit 20.3.2006, 20:06 | ||
Хм... очень странно, а вот так работает:
Кстати какого типа поле day_rojd в таблице? |
| Автор: lenyska 20.3.2006, 21:17 |
| АААААААА!!!!!!! СУПЕР Все работает Спасибо вам ОГРОМЕННОЕ, вы мне очень помогли |
| Автор: Vit 20.3.2006, 23:40 |
| Хм... я то почти и не сомневался что так работает, настараживает тот факт что предыдущий вариант не работал... Очень странно... |
| Автор: lenyska 21.3.2006, 11:06 |
| А меня уже ничего не удивляет. Главное, что работает! И я этому безумно рада |
| Автор: Vit 21.3.2006, 16:14 | ||
Я рад что Вы рады... но обойдя одни грабли случайно стороной не гарантирует шишки следующий раз. Дело Ваше, но желательно разбираться до конца... Это помогает в будущем, по существу вопроса: Дата в формате yyyy-mm-dd hh:nn:ss является стандартом для MS SQL Server и при ЛЮБОЙ локализации клиента и сервера строка в таком формате конвертируется в дату правильно |
| Автор: lenyska 21.3.2006, 18:58 |
| если это является стандартом, почему же тогда в таблицах SQL Serverа он выводит дату как dd.mm.yyyy? и в приложение он выводит дату в таком же формате У меня что, нестандартные настройки в SQL Serverе стоят? но как это может быть, если я ничего не меняла? |
| Автор: Vit 21.3.2006, 23:54 | ||||||
| Нет, попробую расставить точки над i. 1) MS SQL Server сам по себе хранит дату в ввиде дробного числа, где целая часть это число дней пошедших с 30 декабря 1899 года, а дробная - это части дня. Попробую объяснить при помощи псевдокода: если у вас есть в поле дата "21 марта 2006 года, 21:10:00" то - если взять целую часть от даты то будет "21 марта 2006 года" - если взять дробную часть от даты то будет "30 декабря 1899 года, 21:10:00" - один час равен 1/24 единицы в том поле - одна минута равна 1/(24*60) 2) Когда вы вставляете в запрос дату в кавычках, то сервер вначале конвертирует её в своё представление в ввиде дробного числа, а потом оперирует им. НО! Конвертация зависит от используемых национальных установок, вы пишете на дельфи например StrToDateTime('01/02/03') и на вашем компьютере стоят национальные установки российские, то эта функция вернёт дату "01 февраля 2003" года, а если у вас стоят американские установки то эта эе функция вернёт "02 января 2003" года. Обычно при работе с обычным приложением вам на это наплевать, главное что дата всегда конвертируется в пределах вашего приложения одинаково, соответственно вашим национальным установкам. А вот когда начинаем работать с сервером возникают проблемы: у вас может быть русская локаль, а на сервере - американская и строка даты '01/02/03' для сервера и клиента означают РАЗНЫЕ даты! То что я пытался сделать вначале - это послать дату в формате даты, а не строки параметром и предоставить серверу самому интерпретировать её... и был очень удивлён что у Вас это не работает. 3. Когда вы выводите информацию из базы данных, например в грид, то клиентское приложение естественно пытается конвертировать дату из дробного числа в строку, которая была бы понятна для вас, так как вряд ли вы сможете оперировать легко и наглядно с датами записанными как 36263.21312. Даже когда вы просматриваете базу данных используя Query Analyser или MS SQL Server Enterprise Manager - они являются обычными клиентскими программами, такими же как и ваше приложение. Они при показе даты будут и производить конвертацию дробного числа с сервера в строку. Причём существует 4 вида алгоритма конвертации: - Использовать какой-то стандартный, зашитый формат - Использовать формат даты/времени установленный на компьютере где стоит сервер - Использовать формат даты/времени установленный на компьютере где стоит клиент - Не заморачиваться и показывать как бог на душу пошлёт... как многие программисты и делают, даже в MS. Итого: выводит дату в формате dd.mm.yyyy КЛИЕНТСКОЕ приложение а не сервер, формируя её по видимому с учётом ваших локальных клиентских установок, а вот когда вы формируете запрос в таком формате, то сервер получив такую строку и (по-видимому) имея какие-то другие настройки просто не способен её переварить. Итого то что показывает грид - к реальности имеет весьма отдалённое отношение. 4. Программисты из MS предвидели проблемы с конвертацией строк с датой в данные типа "дата-время", поэтому выработали стандарт который позволяет при любых национальных раскладках интерпретировать строку формата YYYY-MM-DD HH:NN:SS всегда правильно. Например у меня стоит американская раскладка и запросы
и
Для моего MS SQL Server абсолютно идентичные, хотя на вашем сервере с русской нацинализацией, только первый мой запрос будет правильным, второй для вас надо будет менять на
Пока вы работаете в пределах одной и той же локалицации вы можете использовать оба запроса, но предпочтителен вариант '2006-01-02' - так как именно он будет гарантировать выполняемость запроса при любых установках сервера |
| Автор: lenyska 24.3.2006, 14:38 |
| Спасибки! Объяснения знающего человека всегда воспринимаются легче, чем текст какой-нибудь книги. Да и не в любой книге найдешь нужную информацию. |
| Автор: Veniamin 24.5.2008, 12:55 | ||||
Помогите пожалуйста. База данных в Access, соединена с программой в Delphi через ADO. В таблицу при добавлении записей типа текст проблем нет, но в БД в Access добавил поле с типом дата, как мне добавлять дату? В таком формате:
|
| Автор: Данкинг 24.5.2008, 13:05 | ||
А зачем 2 раза "text" ? |
| Автор: Veniamin 24.5.2008, 13:13 |
| Данкинг Опечатался, исправил, теперь не ругается. А нет, всё работает. Разобрался. Теперь как запрос составить на вывод записей по диапазону дат заявок? Есть ли разница у SQL-Server-а и MS Access? |
| Автор: Данкинг 24.5.2008, 13:23 | ||||
В общем случае:
(только в твоём случае всякие конвертации типов нужны, разумеется) Конкретно не сравнивал, но разницы между диалектами SQL никто не отменял... |
| Автор: Veniamin 24.5.2008, 13:35 | ||||
Разница всё-таки есть: в SQL-е дата пишется в одинарных кавычках, а в Access-е нужно вместо них писать решётки - #. Сделал следующим образом:
В ADOQuery запрос написать немудрено. Теперь как бы это Edit забить? Пробовал вот так, компилятор ругается:
Вариант в фигурных скобках тоже не работает. |
| Автор: Данкинг 24.5.2008, 14:26 | ||
Понятно, что ругается: в фигурных скобках ты к текстовой строке (т.е. свойство AdoQuery SQL) пытаешься добавить переменную типа "дата". Ну, строчки без скобок понятны: ты дату с текстом сравниваешь. А чтобы Access'у передать переменную типа "дата" попробуй нечто вроде этого:
|
| Автор: Veniamin 24.5.2008, 14:40 | ||||
Попробовал с cdate вот:
Выводится такая ошибка: http://radikal.ru/F/i046.radikal.ru/0805/70/7dd1d6b7bfdc.jpg.html Получилось!!! Сделал! Вот как нужно было:
Большое Вам Спасибо за помощь Данкинг! |
| Автор: Данкинг 24.5.2008, 16:46 |
| Да не за что. |
| Автор: Veniamin 24.5.2008, 17:46 | ||
| После того как поменял типы данных у даты ремонта и даты заявки в базе Аксеса с текстового на дата/время с условием укороченный, т.е. дата в формате 1.01.2008, вообще перестали добавлятся записи в таблицу и редактироватся пустые. Если редактировать уже существующие с заполнеными полями типа дата, то проблем нет. Может что-то здесь неправильно?
При попытки добавить запись или редактировать пустое поле выводится ошибка: http://radikal.ru/F/i034.radikal.ru/0805/82/65568fbe9f01.jpg.html , после чего программа виснет. Может всё из-за того, что я ввожу дату в кратком формате? Пробовал менять StrToDate - тот же результат. |
| Автор: Данкинг 24.5.2008, 20:00 | ||||
| Вообще-то подобный код и не должен выполняться, так как пустое значение действительно не может быть датой. Ну, попробуй (хотя маловероятно, что получится):
Но я бы просто поставил исключение на это дело:
|
| Автор: Veniamin 24.5.2008, 20:17 |
| Данкинг У меня как раз поля на форме для редактирования/добавления записей таким образом и заполняются - с помощью конструкции try...except, и иногда выводится сообщение, которое записано в обработке except: "Невозможно выполнить.", но чаще просто выводится ошибка и программа виснет. На предложенный Вами код - аналогичная реакция. Как тогда лучше сделать заполнение пустых полей в БД Access с типом дата/время? |
| Автор: Данкинг 24.5.2008, 21:32 |
Что-то странное: я обычно так и делаю, т.е. вешаю исключение на могущие быть пустыми поля. |
| Автор: Veniamin 24.5.2008, 22:22 | ||
Вот код, который написан у меня на добавление записи в таблицу:
При попытке добавить или редактировать пустые поля дата ремонта и дата заявки ругается, при редактировании же уже существующих - всё выполняется. Про код я имел ввиду с Fieldvalues. |
| Автор: Данкинг 24.5.2008, 22:30 |
| Не, я имел в виду, что TRY надо поставить перед конкретно оператором заполнения даты! |
| Автор: Veniamin 24.5.2008, 22:39 | ||
А можно использовать вложенную конструкцию try...except, т.е. я просто строчку на добавление даты заключил в эту конструкцию? И всё равно - выводится та же ошибка.
|
| Автор: Данкинг 24.5.2008, 23:02 |
| Ну а если StrToDateTime заменить на StrToDate ? |
| Автор: Veniamin 24.5.2008, 23:15 | ||
| Не получается :( . Та же самая ошибка. А может быть причина в коде при создании самой формы для редактирования? Т.е. если редактирую, чтоб выводились уже существующие поля в Edit-ы. Вот:
|
| Автор: Данкинг 24.5.2008, 23:19 |
| Тогда функций проверки сделай, как я говорил. |
| Автор: Veniamin 24.5.2008, 23:21 |
| Отредактировал пост выше, может в создании формы причина, когда передаю значение формата дата в Edit как строку (AsString)? |
| Автор: Данкинг 24.5.2008, 23:51 | ||
Так ошибка-то на какой строке вылезает? |
| Автор: Veniamin 25.5.2008, 00:09 |
| Код во втором посте сверху этой страницы привёл как возможную причину, а ошибка вылазит при попытке добавить дату ремонта или дату заявки в коде на предыдущей странице. А стрелка появляется сразу же после ошибки возле строки: FormModifyData.ShowModal; , которая приведена выше во втором посте на этой странице. p.s. Действительно ерунда какая-то происходит. Попробовал создать в Access-е базу с единственной таблицей, в которой поля счётчик да дата типа дата. В Delphi кинул на форму всё что нужно для ADO соединения, отобразил таблицу, добавил кнопку на которой событие - добавление записи формата время из Edit1.Text, который находится на этой же форме. Не забыл всё это включить в конструкцию try...except. Запустил... всё добавляется Только что попробовал в своей программе - на дату ремонта ругается дебаггер, но добавляет в пустое поля запись. |
| Автор: Данкинг 25.5.2008, 00:25 |
| В общем, разберись с кодом, где-то там косяк. Кстати, не понял, зачем форму создавать динамически, когда вроде как можно создать обычным способом. |
| Автор: Veniamin 25.5.2008, 00:30 |
| Там столько перелопачивать. |
| Автор: Данкинг 25.5.2008, 00:35 | ||
Не заново писать, а разобраться только с тем, где происходит добавление даты (если всё же функцию проверки писать не хочешь).
А смысл-то в этом какой? Уменьшение размера программы? Дело твоё, конечно, просто это лишняя причина для ошибки. |
| Автор: Veniamin 25.5.2008, 00:41 |
| Может быть и в этом причина. На Delphi с базами мало опыта в программировании. :( А Вы можете посмотреть код пожалуйста? |
| Автор: Данкинг 25.5.2008, 00:42 |
| Могу, только завтра, сейчас уже в код врубаться неохота. |
| Автор: Veniamin 25.5.2008, 00:47 |
| Хорошо, спасибо. |