Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 809

/ вопрос открыт /

Здравствуйте, эксперты!
Программирую на Delphi недавно, ну мож год не больше(хочу научится писать программы хоть на среднем уровне), поэтому не смейтесь за наивные вопросы.
Вобщем дело обстоит так:
1.Есть база данных на SQL Server 2005, писал не я.
2.Наваял я программу которая изменяет некоторые данные в этой базе, все просто чудесно когда региональные настройки
совпадают( тоесть я тестировал на Windows XP RU +SQL Server 2005 Ru и клиенте тож Windows XP Ru).
Но!!! если Windows XP Eng+SQL Server 2005 Eng, а клиент на Windows XP Ru(другие комбинации не пробовал), начинаются косяки с переводом формата Даты и
времени(т.е. прога вываливается с ошибкой, типа немогу конвертировать, неправильная дата), ведь у буржуинов сначало месяц, потом день.
Да, вот еще, в базе данных этот формат хранится с Русскими региональными настройками(т.е. 18.08.2007 01:45:34), и основная программа работает "на ура",
возможно она эти данные пишет через хранимые процедуры, в которых определен формат даты, мне такого нельзя(всмысле писать хранимые процедуры). В связи
с этим вопрос, как мне или какую команду передать на сервер чтоб он записал ДатуВремя по моему формату, и я не гадал бы на какой винде(Ru или Eng) стоит SQL Server.
Если можно, то пример кода приведите, тыкните носом пожалуйста, очень надо, жизнь заставляет.

Vendigo Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Vendigo (статус: Посетитель)
Вопрос отправлен: 8 августа 2008, 02:23
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 25; последнее сообщение — 11 августа 2008, 17:48; участников в обсуждении: 4.

Страницы: [1] [2] [Следующая »]

Вадим К

Вадим К (статус: Академик), 8 августа 2008, 02:52 [#1]:

написали вы много, но важного - крапаль. написали хотя бы каким методом (компоненты) получаете доступ к базе.
Вообще то в базе данных, если всё правильно сделано (то есть дата не храниться в текстовом поле или что то подобное), то нет разницы, какая локаль - дата всё равно храниться в бинарном виде. Проблема возникает в момент самой передачи.
Скорее всего ваши копмоненты надеятся, что данные на том конце совпадают с данными здесь по формату.
Галочка "подтверждения прочтения" - вселенское зло.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 11:25 [#2]:

Доступ к базе данных через ADO(ADOConnection1.ConnectionString:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog='+NameBase+';Data Source='+ServerName+'';), ошибка вываливается в момент записи данных на сервер, вот код:
frMain.ADOQuery5.Parameters.ParamByName('EDT').Value:=NewEventTime; // Определили Новое время для события
Вот сама SQL команда- UPDATE Events
SET EventDateTime=:EDT(ДатаВремя, тут ошибка, если я правильно думаю), EventTypeID=:ET,
Description=:ED, Computer=:EC,
UserFullName=:EU
WHERE EventID=:EDS
Тоесть запрос к базе идет через параметры, вот, вроде обьяснил, извините если не понятно, неумею толком обьяснять...
Вадим К

Вадим К (статус: Академик), 8 августа 2008, 13:02 [#3]:

параметры собираются на клиенте и в этот момент он не в курсе, какая кодировка на сервере.
что же делать.
вариант 1) изменить на клиенте локаль. это можно сделать для программы отдельно.
вариант 2) передавать дату в унифицированном варианте. Это такой
#MM/DD/YYYY#. В таком виде MSSQL server понимает независимо от локали.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 8 августа 2008, 14:45 [#4]:

есть еще вариант: обойтись при конструировании команды без параметров. Т.е. формировать полностью команду в текстовую переменную. При этом передавать дату в символьном формате, используя DateToStr в этом случае SQL сервер сам преобразует строковый формат в формат даты независимо от установок.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 14:57 [#5]:

Спасибо за ответ.
Второй вариант мне нравится больше, если можно напишите пример кода. В кратце расскажу суть выполняемых действий:
есть таблица, содержит данные, которые если изменить то срабатывает триггер и пишет данные в другую таблицу, старое
значение и новое, вот эти значения мне и надо заменить на стандартные типа открыта форма -закрыта форма, кроме того
там есть поле (TDateTime), естественно что для событий открыть форму и закрыть время не может
быть одинаково, вот его я и изменяю, считываю без проблем, изменяю время тож, а записать,если локали разные немогу).
Еще раз большое спасибо за помощь.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 15:01 [#6]:

И еще хотелось бы почитать про использование функции, описанной
Мережниковым Андреем (SQL: convert(<тип данных>,<выражение>,<стиль>;)). И если возможно, то пример кода использующий эту функцию.
Вадим К

Вадим К (статус: Академик), 8 августа 2008, 15:28 [#7]:

Мережников Андрей немного неверно сказал вам, Vendigo. DateToStr вам не поможет, так как он полностью от локали зависит.
Галочка "подтверждения прочтения" - вселенское зло.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 15:31 [#8]:

По поводу формирования команды, я передаю датувремя как строку, SQL Server сам конвертирует дату, тоесть если я передам '24.08.2008 01:23:35' то сервер попробует записать как 08.24.2008 01:23:35, что не является допустимым, так как 24 месяца нету(ОС на которой стоит сервер - Eng), вот в чем проблема, как мне "сказать" серверу что пиши дату как тебе дали. Спасибо за ответ.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 8 августа 2008, 15:33 [#9]:

про использование функции convert можно подробнее почитать в help по SQL server, либо в книге по языку SQL (лучше для MS SQL Server любой версии). Пример кода: s:='update <имя таблицы> set <имя поля>='+DateToStr(<переменная, в которой записано значение даты>);Затем записываете это в компонент ADO для внесения изменений (например в ADOQuery): ADOQuery.SQL.clear;ADOQuery.SQL.ADD(s); и выполняете.Если необходимо кроме даты записывать еще и время, то вместо DateToStr используете DateTimeToStr. Пробуйте. Если не получится, пишите. Можно в личную зону.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 8 августа 2008, 15:46 [#10]:

Вы уверены, что ругается на такой форммат даты? Дело в том, что MS SQL использует определенный набор форматов представления даты. И если разделителями между частями даты идут точки, то на первом месте может стоять либо день, либо год. Номер месяца может стоять на первом месте только если в качестве разделителя используется пробел, либо слэш, либо тире
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 15:52 [#11]:

Спасибо за ответ Мережников Андрей.
Попробую воспользоватся вашим советом,
смогу проверить через часов 4-5, нужно установить SQL Server Eng, у меня Ru. SQL команды передаются на сервер с параметрами, нельзя нагружать сервер(разбор запроса и составление плана выполнения), потому как интересуемая база данных не одна на сервере. Ну чтоб было понятнее приведу кусок кода:

If EventType<>'2' Then // Если ID события отличный от 2(2-это типа открыть, закрыть- 1 это косяк для нас)
begin
NewEventDesc:=EventOrder(PrevEventDesc);//послали описание Предыдущего события и получили взамен что надо написать
NewEventTime:=EventChangeDateTime(PrevEventTime);//послали время (Предыдущее)и получили измененное время
frMain.ADOQuery5.Active:=False; // Запрос в Оффлайн, Щас будем собирать Новую строку, чтоб скрыть косяк
frMain.ADOQuery5.Parameters.ParamByName('EDS').Value:=EventsID; // Определили в запросе в какую строку будем писать
frMain.ADOQuery5.Parameters.ParamByName('EDT').Value:=NewEventTime; // Определили Новое время для события
frMain.ADOQuery5.Parameters.ParamByName('ET').Value:=NewEventType; // Определили Новый тип события
frMain.ADOQuery5.Parameters.ParamByName('ED').Value:=NewEventDesc; // Определили Новое описание события
frMain.ADOQuery5.Parameters.ParamByName('EC').Value:=NewEventComp; // Определили Имя компьютера, указывается в настройках
frMain.ADOQuery5.Parameters.ParamByName('EU').Value:=NewEventUser; // Определили Полное имя(сетевое), указывается в настройках
frMain.ADOQuery5.ExecSQL;// Отправили команду на обновление записей выбранной строки
If Index=EventRecordCount then CorrectRecord();// Если это последняя запись, то вызываем Функцию корректировки последней записи вдруг накосячили и у нас 2 раза в логе закроется форма, а такого нельзя
frMain.StatusBar1.Panels[0].Text:='Обработано- '+IntToStr(Index)+' записей';
Connect();// вызываем процедуру обновления Набора данных
frMain.StatusBar1.Refresh;
frMain.DBGridEvents.DataSource.DataSet.Last;//Стали на последнюю запись
exit;// выходим из процедуры
end;
это только кусок кода, но формирование строки для записи должно быть понятно(ну мне так кажется), возможно ошибаюсь.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 16:00 [#12]:

Ответ на сообщение от 8 августа 2008, 15:46:
Дело в том что программа работает и не выдает ошибку, если день не больше 12, тоесть 12.08.2008 нормально отработает(правда запишет сервер дату как 08.12.2008), но вот 13.08.2008 он не сможет обработать.
Вадим К

Вадим К (статус: Академик), 8 августа 2008, 16:05 [#13]:

если локаль американская, то на первом месте всегда месяц, потом день. как не крути. именно по этой причине одна с первых версий Word была выпущена 11 ноября (11.11).
Поэтому, надо формировать ручками и не морочить себе голову. попробуйте в том формате, который я написал. он обязан работать.
Галочка "подтверждения прочтения" - вселенское зло.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 16:24 [#14]:

Ответ на вопрос от 8 августа 2008, 16:05
А можно поподробнее и применительно к моему коду, тоесть к строке
frMain.ADOQuery5.Parameters.ParamByName('EDT').Value:=NewEventTime; // как мне ее форматнуть чтоб дата записалась мне нужная.Я конечно могу наваять функцию чтоб меняла местами месяц и дату но этож неправильно, или я неправильно думаю?
Вадим К

Вадим К (статус: Академик), 8 августа 2008, 16:43 [#15]:

лучше отказаться от параметров. у ADO с ними есть один глюк неприятный, который может позже всплыть.
я всегда делал прямое формирование запроса. то есть где то так
ADOQuery1.SQL.Text := 'select .......';
ADOQuery1.Execute;

а для даты можно воспользоваться готовыми функциями. буду дома - могу написать (скопировать с своего проекта) готовые функции для формирования даты правильном формате.
Галочка "подтверждения прочтения" - вселенское зло.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 17:32 [#16]:

Если возможно, не могли Вы бы сказать какие глюки, плюс если возможно, напишите функцию для формирования даты, если конечно это не перестановка месяца в первую позицию, хотя это тож пойдет. Хотя я считаю, это не правильно, ДатаВремя должно передаватся в универсальном формате, чтоб его мог понять SQL Server и Eng и Ru.
Вадим К

Вадим К (статус: Академик), 8 августа 2008, 17:45 [#17]:

Формат передачи я уже писал. именно с решётками по бокам. Это указание серверу, что передаётся независимо от локали. Сейчас по памяти не могу написать, а дома точно есть работающая функция, которая форматирует дату независимо от локали.
а глюки... АДО парсит запрос на лету. И в некоторых случаях даже при правильно составленном запросе приходят ошибки, что неверно сотавлен запрос.
Галочка "подтверждения прочтения" - вселенское зло.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 19:03 [#18]:

А можно написать пример команды , с использованием этого формата, ато я не совсем понимаю как мне это реализовать -DD/MM/YYYY#. Желательно пример к моему коду, уж очень нехочу переходить к запросам без параметров. Еще раз спасибо за понимание и ответы, извините за наивные вопросы.
Вадим К

Вадим К (статус: Академик), 8 августа 2008, 19:42 [#19]:

вы внимательно читаете, что я пишу в нескольких последних постах? я на РАБОТЕ. А точно работающий код есть дома. а буду я там через несколько часов.
Галочка "подтверждения прочтения" - вселенское зло.
Vendigo

Vendigo (статус: Посетитель), 8 августа 2008, 20:20 [#20]:

Вадим К., СПАСИБО Вам огромное, я подожду когда Вы освободитесь.
Хорошо что есть этот сайт где можно спросить, ато я потерялся и не знаю что делать, сразу казалось проблема простая, ан нет- сложная.
Спасибо Всем кто откликнулся, хотя вопрос еще не решен, но всеравно спасибо за ответы.

Страницы: [1] [2] [Следующая »]

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:26
Выполнено за 0.03 сек.