Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.09.14;
Скачать: CL | DM;

Вниз

ADO и параметры   Найти похожие ветки 

 
Evgeny V ©   (2008-03-14 09:38) [0]

Имеется MS SQL 2005, поле в базе типа DateTime, D6 и ADO и Студия 2005 и ADO.NET.
Есть запрос на вставку примерно такого плана для дельфи и ADO

Insert into TxRxAnalize (OperData,Duration, Base) VALUES (:P1,:P2,:P3)

(заполнение параметра происходит примерно так

AdoQuery1.Parameters.ParamByName("P1").Value:=Now; )

и для студии и ADO.NET

Insert into TxRxAnalize (OperData,Duration, Base) VALUES (@P1,@P2,@P3)

OperData - тип DateTime в базе данных.

При выполнении запроса через дельфи6-ADO ,усекается OperData до секунд, миллисекунды обнуляются. При выполнении этого запроса через ADO.NET или через ADO, но  без параметров (передаю явные значения) - усечения не происходит.  Такое же усечение наблюдается и для типа данных
Decimal при передаче значения через параметр...

Вопрос, где у меня ошибка для связки дельфи-ADO, или это его ограничение??


 
Evgeny V ©   (2008-03-14 09:59) [1]

Что бы удобнее искать строку #17

Так происходит усечение

procedure TMainForm.InsertRecord;
var
 par: Tparameter;
begin
 Aq1.SQL.Text := " insert into TxRxAnalize (OperData,Duration, Base) VALUES (:P1,:P2,:P3)";
 par:=Aq1.Parameters.FindParam("P1");
 par.Value:=Now;
 par:=Aq1.Parameters.FindParam("P2");
 par.Value:=0.3985214778;
 par:=Aq1.Parameters.FindParam("P3");
 par.Value:=1;
 Aq1.ExecSQL;
end;

Так НЕ происходит усечение

procedure TMainForm.InsertRecord;
begin
 Aq1.SQL.Text := " insert into TxRxAnalize (OperData,Duration, Base) VALUES (""15/03/2008 14:22:03.887"",0.3985214778,1)";
  Aq1.ExecSQL;
end;


 
Johnmen ©   (2008-03-14 10:06) [2]


>  par:=Aq1.Parameters.FindParam("P1");
> ...

Зачем такие танцы?
Почему бы по-человечески не написать Aq1.Parameters.ParamByName("P1").Value:=Now;?


 
Evgeny V ©   (2008-03-14 10:18) [3]


> Johnmen ©   (14.03.08 10:06) [2]

 -согласен, короче и удобнее и читабельнее -
так и было вначале, но  на суть не влияет, ибо то же самое делается в ParamByName...

Вопрос про усечение в силе


 
sniknik ©   (2008-03-14 10:24) [4]

> миллисекунды обнуляются. При выполнении этого запроса через ADO.NET или через ADO, но  без параметров (передаю явные значения) - усечения не происходит.
не знаю как в ADO.NET передается, а в ADO параметры передаются через варианты, а в варианте в дататайме миллисекунд нет... (было так во всяком случая, когда проверял. давно)

> Такое же усечение наблюдается и для типа данных Decimal при передаче значения через параметр...
а вот это неправда... если именно тип Decimal, хотя если денежный то допускаю, там действительно только 4 знака после запятой. посмотри если гдето внутри к currency приводится то...
передавай через тип с плавающей запятой (double например).


 
ЮЮ ©   (2008-03-14 10:27) [5]

Странное желание записывать на сервере показания часов на клиенте. Не лучше ли в триггере проставлять серверное время.

Но даже записав так

CREATE TRIGGER TrustedConnections_OnInsert ON dbo.TrustedConnections
INSTEAD OF INSERT
AS
BEGIN
 INSERT INTO TrustedConnections(
   [StudentConnection],
   [TeacherConnection],
   [Test],
   [Started],
   [Finished]
 )
 SELECT
   [StudentConnection],
   [TeacherConnection],
   [Test],
   GetDate(),
   case when [Finished] IS NULL then NULL else GetDate() end
 FROM
   inserted
END


я при обычном просмотре таблицы в Manager-е не наблюдаю милисекунд.

Но это проблема отображения, а не отсечения, ибо выполнив
select * from dbo.TrustedConnections
в SQL Explorer-е я наблюжаю datetime поля в ином, отличном от Manager-а, формате и вижу, что мс там присутствуют.


 
sniknik ©   (2008-03-14 10:36) [6]

> Не лучше ли в триггере проставлять серверное время.
на инсерт ка у тебя дальше? имхо не лучше, лучше тогда уж просто при создании таблицы поставить GetDate() полю как дефаултное значение.


 
ЮЮ ©   (2008-03-14 10:43) [7]

> на инсерт ка у тебя дальше?

Не понял?

>имхо не лучше
А то что на часах клиенте можно накрутить любое время, конечно, лучше :)


 
Evgeny V ©   (2008-03-14 10:58) [8]


> sniknik ©   (14.03.08 10:24) [4]


> не знаю как в ADO.NET передается, а в ADO параметры передаются
> через варианты, а в варианте в дататайме миллисекунд нет.
> .. (было так во всяком случая, когда проверял. давно)

Спасибо.


> а вот это неправда... если именно тип Decimal, хотя если
> денежный то допускаю, там действительно только 4 знака после
> запятой. посмотри если гдето внутри к currency приводится
> то...
> передавай через тип с плавающей запятой (double например).
>


Тип Decimal(numeric(25,18)) - создал дополнительно в базе поле этого типа, а передал ему DateTime параметром как double, получил округление -сравнил два поля по значению в записи и то, что реально ложилось в параметры (лог в мемо), разница налицо между полями и логом.
При передаче без параметров - разницы почти нет (меньше) между полем типа DateTime и numeric, и нет между numeric и логом.

Спасибо за  информацию про Variant


> ЮЮ ©   (14.03.08 10:27) [5]


> Странное желание записывать на сервере показания часов на
> клиенте. Не лучше ли в триггере проставлять серверное время


Желания могут быть разные, например принесли лог-файл с уже прописанными значениями(в том числе и датой временем) для дальнейшего анализа в базе. Через ADO.NET сохраняется без проблем, но попросили сделать утилиту именно в дельфи и через ADO, а так как с ADO я раньше почти не сталкивался, то и вот и возникли вопросы по проблемам...  
Итог -
Оставил пока запросом без параметров...


 
Evgeny V ©   (2008-03-14 11:05) [9]


> ЮЮ ©   (14.03.08 10:27) [5]
> Но это проблема отображения, а не отсечения, ибо выполнив
> select * from dbo.TrustedConnections
> в SQL Explorer-е я наблюжаю datetime поля в ином, отличном
> от Manager-а, формате и вижу, что мс там присутствуют.


смотрю именно  select


 
sniknik ©   (2008-03-14 11:06) [10]

> Не понял?
ну ты приводишь пример триггера

> А то что на часах клиенте можно накрутить любое время, конечно, лучше :)
я разве предлагал? замена триггеру ->
> лучше тогда уж просто при создании таблицы поставить GetDate() полю как дефаултное значение.

> разница налицо между полями и логом.
ошибка в программе?
будь проще - пример запроса, тип поля, как вносишь, чем смотришь в чем разница. на пальцах. а то если разница например в 18 м знаке и для типа (участие наверняка есть) с плававающей запятой... вполне нормально.


 
Evgeny V ©   (2008-03-14 11:14) [11]

Пример запроса Insert я привел, а лог пишу значение параметра Format("%.18f",[par])  (но оно у меня то же в пришедшем файле),

- при передаче через параметр разница как ты и сказал после 4 знака. При прямом запросе разницы нет для поля numeric и много меньше для поля DateTime - в 7 знаке, что в принципе устраивает


 
sniknik ©   (2008-03-14 11:25) [12]

> а лог пишу значение параметра Format("%.18f",[par])
f - float, т.е. число с плавающей запятой. см. их свойства (на королевстве дельфи статью поищи)

> разница как ты и сказал после 4 знака
я говорил про каренси, денежный тип, если бы у тебя было преобразование/приведение через него то была бы не просто разница после 4 знака, а после него просто не было бы ничего, одни сплошные нули.

> При прямом запросе разницы нет для поля numeric
что значит "прямой запрос"? это какойто новый термин которого я еще не знаю? и если есть "прямой" то значит и "кривой" должен быть?
не выделывайся, пальцем покажи...

> и много меньше для поля DateTime - в 7 знаке
DateTime как число? оригинально, ничего невозможного конечно тотже double, но хочу тебя огорчить, тут возможна разница не после запятой, а перед... точка отсчета "начала дней" в делфе и mssql не совпадает.


 
Evgeny V ©   (2008-03-14 11:42) [13]


> sniknik ©   (14.03.08 11:25) [12]

прямой запрос - запрос без парметров, просто так показалось короче и понятней, извини:-)


> DateTime как число? оригинально

Да как число - это делалось для проверки, что же происходит с параметрами, и отражается ли это на на другие типы полей или только на DateTime.


> f - float, т.е. число с плавающей запятой. см. их свойства
> (на королевстве дельфи статью поищи)


В этом месте у меня проблем нет, так как мне пришла дата в виде числа с точкой и записал  в лог параметр в этом же виде, они совпали до знака во входном файле и в моем логе.


> я говорил про каренси, денежный тип, если бы у тебя было
> преобразование/приведение через него то была бы не просто
> разница после 4 знака, а после него просто не было бы ничего....
>  одни сплошные нули.


Именно так оно в базе и происходит для запроса с параметрами.


 
sniknik ©   (2008-03-14 11:49) [14]

> Именно так оно в базе и происходит для запроса с параметрами.
back
sniknik ©   (14.03.08 10:24) [4]
> передавай через тип с плавающей запятой (double например).


 
Evgeny V ©   (2008-03-14 11:53) [15]

sniknik ©   (14.03.08 11:49) [14]
> DateTime как число? оригинально


> Да как число - это делалось для проверки, что же происходит
> с параметрами, и отражается ли это на на другие типы полей
> или только на DateTime


С тем же результатом.....

> Evgeny V ©   (14.03.08 10:58) [8]


 
sniknik ©   (2008-03-14 11:55) [16]

> Decimal
в дельфи ближайший тип это BCD, но нормальной работы с ним в "базовых" компонентах нет... все через карренси. либо меняй тип поля, либо делай собственную обработку.


 
Evgeny V ©   (2008-03-14 12:06) [17]


> sniknik ©   (14.03.08 11:55) [16]

Спасибо за помощь:-))


 
Anatoly Podgoretsky ©   (2008-03-14 18:17) [18]

> sniknik  (14.03.2008 11:25:12)  [12]

> DateTime как число? оригинально, ничего невозможного конечно тотже double, но хочу тебя огорчить, тут возможна разница не после запятой, а перед... точка отсчета "начала дней" в делфе и mssql не совпадает.

DateTime в mssql не float и не double
Поэтому попытки работы с ним как с float ни к чему хорошему не приведут.

--


 
piople   (2008-03-17 06:21) [19]

To Evgeny V ©  Дядь Жень, не знаю поможет вам это или нет - http://www.sql.ru/faq/faq_topic.aspx?fid=103


> Целая часть DateTime Представляет из себя количество суток.
>  Дробная часть имеет длину в 8 знаков. 3.33 милисекунды
> из BOL соответсвуют 0.00000002.
> 1. Вопрос. Мой клиент не правильно передает значение DateTimе
> серверу.
> Всегда используйте передачу значения DateTime в виде строки.
>  
>
> Подготовленное для передачи значение должно быть представлено
>
> в формате ISO - "yyyymmdd hh:mm:ss.mmm"


P.S. Я почему-то не могу найти Ваш контакт в асе, плиз постучите, или скиньте на мыло номер...


 
Evgeny V ©   (2008-03-17 07:22) [20]


> piople   (17.03.08 06:21) [19]

Спасибо:-)


 
ANB   (2008-03-17 10:33) [21]


> piople   (17.03.08 06:21) [19]

+1. Еще неплохо на входе уже в запросе явно преобразовать в дату с маской - тогда настройки сервера и клиента никогда не повлияют.


 
Anatoly Podgoretsky ©   (2008-03-18 04:31) [22]


> > Целая часть DateTime Представляет из себя количество суток.
>
> >  Дробная часть имеет длину в 8 знаков. 3.33 милисекунды
>

Кто такую глупость написал?
Ни каких дробных частей, ну не хранит как флоат.
В остальном тоже ошибки - "yyyymmdd hh:mm:ss.mmm"  - это не вормат ISO и более того он не будет работать.

Поосторожнее с Интернетом, очень много грязи.


 
piople ©   (2008-03-18 08:10) [23]

Неисключено :)

Из SQL Server Books Online:

> In SQL Server 7.0 and SQL Server 2000, bcp uses the ODBC
> bulk copy API. Therefore, bcp uses the ODBC date format
> (yyyy-mm-dd hh:mm:ss[.f...]) to import date values


Значитъ использует:

> ODBC canonical (with milliseconds) yyyy-mm-dd hh:mi:ss.mmm(24h)


Возможно ошиблись в статье, но вот еще выдержка с сайта microsoft(MSDN)
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2616395&siteID=1

Получаетцц0:
Select Convert(nvarchar,date,126) from yourtablename

this will return yyyy-mm-ddThh:mms.mmm format

Айс?


 
piople ©   (2008-03-18 08:16) [24]

Извените что не сразу в одном сообщении, вообщем проверил на своей БД:
SELECT     CONVERT(nvarchar, TDate, 126) AS DateTimeWithMS
FROM         SiteGuestBook


Result:
2008-01-02T16:27:51.670
2008-01-02T23:33:13.030
2008-01-02T23:33:16.780
2008-01-02T23:33:21.593
2008-01-02T23:33:24.640
2008-01-02T23:33:29.543
.....


Либо так:
SELECT     CONVERT(nvarchar, TDate, 121) AS DateTimeWithMS
FROM         SiteGuestBook


Это более удобочитаемо:

2008-01-02 16:27:51.670
2008-01-02 23:33:13.030
2008-01-02 23:33:16.780
2008-01-02 23:33:21.593
....


 
sniknik ©   (2008-03-18 08:35) [25]

> Возможно ошиблись в статье
не ошиблись "yyyymmdd" работает
CREATE TABLE #DateTable (Dat DateTime)
INSERT INTO #DateTable (Dat) VALUES ("20000101 23:59:59.099")
INSERT INTO #DateTable (Dat) VALUES ("20010202 23:58:58.098")
SELECT CONVERT(VarChar(30), Dat, 121)  FROM #DateTable
DROP TABLE #DateTable


и дискретность в миллисекундах присутствует, а вот при чем там дробная часть в 8 символов не понятно.
имелись ввиду байты? но там насколько знаю весь дататайм 8 байт (рекорд из 2х интеджеров), а не только "дробной".
или символы в строковом представлении? но тогда их 9. легко посчитать.


 
Evgeny V ©   (2008-03-18 10:32) [26]


> piople   (17.03.08 06:21) [19]



> P.S. Я почему-то не могу найти Ваш контакт в асе, плиз постучите,
>  или скиньте на мыло номер...


Почты твоей нет, моя ася 246-886-495



Страницы: 1 вся ветка

Текущий архив: 2008.09.14;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.018 c
2-1217453505
Alex_Storm
2008-07-31 01:31
2008.09.14
Добавить строки в ListViev


2-1217469118
Vitaliy____
2008-07-31 05:51
2008.09.14
Нетипизированные указатели


2-1217517743
altatr
2008-07-31 19:22
2008.09.14
Использование процедур


11-1193034025
Дмитрий Пырин
2007-10-22 10:20
2008.09.14
проблема с Bitmap.LoadFromFile


2-1217634273
demon
2008-08-02 03:44
2008.09.14
Конвертация bmp из ресурсов и иконку