![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Опять про даты в 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