Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Опять про даты в MSSQL, но другое [D7, MSSQL]


sergey18 ©   (2005-01-12 16:01:00) 

Проблема такая: поставил MS SQL Server, возможно не совсем корректно, т.к. имел мало опыта общения с ним. И в итоге был удивлен тем, что при добавлении или изменении поля типа DateTime в любой таблице, вариант с форматом Год-месяц-день не проходит. Он мне их менял местами и в итоге при запросе:
INSERT INTO TestTable (TestDate) VALUES ('2004-5-1')добавлялось в базу не 1 марта 2004, а 5 января 2004. А при запросе:
INSERT INTO TestTable (TestDate) VALUES ('2004-5-25')выдавалась ошибка "The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.".

Правильным запросом SQL Server считал такой:
INSERT INTO TestTable (TestDate) VALUES ('25.05.2004')

Пришлось писать программу, которая использовала именно этот формат даты в запросе. Спорить не буду, может я чего-нибудь и намудрил с датами при установке MSSQL.

А теперь по прошествию времени, когда программа уже написана, она по необходимости перенесена на другой сервер, где MS SQL настроен правильно - т.е. ситуация с запросами там прямо противоположная.

Вопрос: Знаю, что MSSQL хранит дату в числовом виде, поэтому подскажите, пожалуйста, как и где можно указать MS SQL Server'у формат принимаемой (понимаемой даты), т.е. изменить его с Год-Месяц-День, на День.Месяц.Год?

P.S. Исходники программы менять не могу, т.к. очень мало времени, а программа - довольно-таки внушительных размеров. В спешке боюсь забыть где-то что-то не поменять и начнутся проблемы, возможно даже не сразу, а впоследствии, когда уже трудно будет понять, что и из-за чего...

Спасибо, искренне надеюсь на вашу помощь!


sniknik   (2005-01-13 10:48:00) [1]

чего только люди не придумают лижбы правильно не делать... параметры зачем по вашему?

KSergey ©   (13.01.05 09:44) [7]
это замена функций
FormatDateTime('yyyymmdd', dtmDateTime)
FormatDateTime('yyyymmdd hh":"nn":"ss', dtmDateTime)
?

тебе наверное построчно платят. ;о)))


Ega23   (2005-01-13 10:29:00) [2]

1) А что это за функция? Не совсем понятно для чего она...

Для динамического формирования запроса. Например:
      ss:='exec S_PersEdit @mode=3, @PersID='+
  DMpas.RQPers.FieldByName('PersID').AsString+','+
 '@UserPersID='+Valx(SessInfo.PersId,',')+'@UserWorkCod='+Valx(SessInfo.Workcod);


KSergey   (2005-01-13 09:44:00) [3]

> [6] sergey18   (12.01.05 16:27)
> Расскажу для других пользователей, которые возможно тоже
> столкнуться с подобной проблемой:

Это не проблема. Это издевательство.
Лучше все же переписать прогу, что как правило не страшно а даже полезно
Да и изменения тут скорее косметического характера.

Вот 2 ф-ции, конфертят с строку, годную для подстановки в SQL-запрос.
Хотя, признаться, не уверен, что написаны они хорошо, но работают стопудово.

// -------- преобразует из типа даты в текстовый, подходящий для подстановки в запросы -----
function DateToMSSQLString (const dtmDateTime : TDateTime) : String; // для MSSQL
var s_Year, s_Month, s_Day: string;
   Year, Month, Day: word;
begin
 Year:=0; Month:=0; Day:=0;
 DecodeDate(dtmDateTime, Year, Month, Day);
 s_year:=IntToStr(Year);
 s_Month:=IntToStr(Month); if Month<10 then s_Month:='0'+s_Month;
 s_Day:=IntToStr(Day); if Day<10 then s_Day:='0'+s_Day;
 Result:=s_Year+s_Month+s_Day;
end;
// -------- преобразует из типа даты-время в текстовый, подходящий для подстановки в запросы -----
function DateTimeToMSSQLString (const dtmDateTime : TDateTime) : String;  // для MSSQL
// Формирование такой строки, кот. правильно понимает сервер:  '20040620 hh:mm:ss'
var s_Year, s_Month, s_Day, s_hour, s_min, s_sec: string;
   Year, Month, Day, Hour, Min, Sec, MSec: word;
begin
 Year:=0; Month:=0; Day:=0;
 DecodeDate(dtmDateTime, Year, Month, Day);
 Hour:=0;Min:=0;Sec:=0;MSec:=0;
 DecodeTime(dtmDateTime, Hour, Min, Sec, MSec);
 s_year:=IntToStr(Year);
 s_Month:=IntToStr(Month); if Month<10 then s_Month:='0'+s_Month;
 s_Day:=IntToStr(Day); if Day<10 then s_Day:='0'+s_Day;
 s_hour:=IntToStr(Hour); if Hour<10 then s_hour:='0'+s_hour;
 s_min:=IntToStr(Min); if Min<10 then s_min:='0'+s_min;
 s_sec:=IntToStr(Sec); if Sec<10 then s_sec:='0'+s_sec;
 Result:=s_Year+s_Month+s_Day+' '+s_hour+':'+s_min+':'+s_sec;
end;


sergey18   (2005-01-12 16:27:00) [4]

2 Johnmen:
Спасибо!!! Помогло! Для меня подошел последний вариант.

Расскажу для других пользователей, которые возможно тоже столкнуться с подобной проблемой:
Нужно задать подходящий language для используемого sql login-а. С помощью утилиты Enterprise Manager.
Это ведет к неявному выполнению SET DATEFORMAT при установлении коннекта. Правда эта установка будет влиять и на результаты некоторых других функций. Например, на DATENAME, возвращающую символьное именование даты


sergey18   (2005-01-12 16:21:00) [5]

2 Ega23:
1) А что это за функция? Не совсем понятно для чего она...
2) Функции мне уже поздно вставлять... Я не хочу менять код программы, я хочу поменять восприятие MS SQL Server'а... Ведь это же возможно?
3) В твоей функции используется не совсем понятная функция "NumsOnlyS", которую Delphi не знает.


Johnmen   (2005-01-12 16:20:00) [6]

http://www.sql.ru/faq/faq_topic.aspx?fid=109


sergey18   (2005-01-12 16:15:00) [7]

2 Fay:
Спасибо за совет, но мне уже поздно - программа написана под тот формат. В следующий раз буду пользовать '20040105'.

Мне нужно, чтобы SQL Server понимал запрос вида:
INSERT INTO TestTable (TestDate) VALUES ('01.05.2004')


Ega23   (2005-01-12 16:13:00) [8]


const
 SQLDateTimeFmt='"{ts''" yyyy-mm-dd hh:nn:ss"'' }"';

Function Valx( i:Variant;d:string=''):string;{ret: <Str_of_Var>, }
//var //ss:string;
  // n:numeric;
begin
result:='';
try
case VarType(i) of
 varEmpty,//    = $0000;
 varNull: result:='Null'+d;
 varString: result:=''''+i+''''+d ;
 varDate: begin
           DateTimeToString(result,SQLDateTimeFmt,i);
           result:=result+d ;
          end;
 varDouble,
 varSingle: result:=NumsOnlyS(VarToStr(i)) +d;
else result:=VarToStr(i)+d;
end;//case
except
result:='';exit;
end;
end;


Fay   (2005-01-12 16:05:00) [9]

'20040105' = 5 января 2004. Прокатит всегда
А ваще, смотри в BOL на convert


Наверх

Титульная страница Поиск, карта сайта Написать письмо