|
Вопрос # 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 (статус: Посетитель)
Вопрос отправлен: 8 августа 2008, 02:23
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 25; последнее сообщение — 11 августа 2008, 17:48; участников в обсуждении: 4.
Страницы: [1] [2] [Следующая »]
|
Вадим К (статус: Академик), 8 августа 2008, 02:52 [#1]:
написали вы много, но важного - крапаль. написали хотя бы каким методом (компоненты) получаете доступ к базе.
Вообще то в базе данных, если всё правильно сделано (то есть дата не храниться в текстовом поле или что то подобное), то нет разницы, какая локаль - дата всё равно храниться в бинарном виде. Проблема возникает в момент самой передачи.
Скорее всего ваши копмоненты надеятся, что данные на том конце совпадают с данными здесь по формату.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
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 (статус: Посетитель), 8 августа 2008, 14:57 [#5]:
Спасибо за ответ.
Второй вариант мне нравится больше, если можно напишите пример кода. В кратце расскажу суть выполняемых действий:
есть таблица, содержит данные, которые если изменить то срабатывает триггер и пишет данные в другую таблицу, старое
значение и новое, вот эти значения мне и надо заменить на стандартные типа открыта форма -закрыта форма, кроме того
там есть поле (TDateTime), естественно что для событий открыть форму и закрыть время не может
быть одинаково, вот его я и изменяю, считываю без проблем, изменяю время тож, а записать,если локали разные немогу).
Еще раз большое спасибо за помощь.
|
|
Vendigo (статус: Посетитель), 8 августа 2008, 15:01 [#6]:
И еще хотелось бы почитать про использование функции, описанной
Мережниковым Андреем (SQL: convert(<тип данных>,<выражение>,<стиль> ). И если возможно, то пример кода использующий эту функцию.
|
|
Вадим К (статус: Академик), 8 августа 2008, 15:28 [#7]:
Мережников Андрей немного неверно сказал вам, Vendigo. DateToStr вам не поможет, так как он полностью от локали зависит.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
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 (статус: Посетитель), 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 (статус: Посетитель), 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 (статус: Посетитель), 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 (статус: Посетитель), 8 августа 2008, 17:32 [#16]:
Если возможно, не могли Вы бы сказать какие глюки, плюс если возможно, напишите функцию для формирования даты, если конечно это не перестановка месяца в первую позицию, хотя это тож пойдет. Хотя я считаю, это не правильно, ДатаВремя должно передаватся в универсальном формате, чтоб его мог понять SQL Server и Eng и Ru.
|
|
Вадим К (статус: Академик), 8 августа 2008, 17:45 [#17]:
Формат передачи я уже писал. именно с решётками по бокам. Это указание серверу, что передаётся независимо от локали. Сейчас по памяти не могу написать, а дома точно есть работающая функция, которая форматирует дату независимо от локали.
а глюки... АДО парсит запрос на лету. И в некоторых случаях даже при правильно составленном запросе приходят ошибки, что неверно сотавлен запрос.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Vendigo (статус: Посетитель), 8 августа 2008, 19:03 [#18]:
А можно написать пример команды , с использованием этого формата, ато я не совсем понимаю как мне это реализовать -DD/MM/YYYY#. Желательно пример к моему коду, уж очень нехочу переходить к запросам без параметров. Еще раз спасибо за понимание и ответы, извините за наивные вопросы.
|
|
Вадим К (статус: Академик), 8 августа 2008, 19:42 [#19]:
вы внимательно читаете, что я пишу в нескольких последних постах? я на РАБОТЕ. А точно работающий код есть дома. а буду я там через несколько часов.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Vendigo (статус: Посетитель), 8 августа 2008, 20:20 [#20]:
Вадим К., СПАСИБО Вам огромное, я подожду когда Вы освободитесь.
Хорошо что есть этот сайт где можно спросить, ато я потерялся и не знаю что делать, сразу казалось проблема простая, ан нет- сложная.
Спасибо Всем кто откликнулся, хотя вопрос еще не решен, но всеравно спасибо за ответы.
|
Страницы: [1] [2] [Следующая »]
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|