Конференция "Базы" » ADO и параметры [D6, MSSQL]
 
  • Evgeny V © (14.03.08 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 © (14.03.08 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 © (14.03.08 10:06) [2]

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

    Зачем такие танцы?
    Почему бы по-человечески не написать Aq1.Parameters.ParamByName('P1').Value:=Now;?
  • Evgeny V © (14.03.08 10:18) [3]

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

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

    Вопрос про усечение в силе
  • sniknik © (14.03.08 10:24) [4]
    > миллисекунды обнуляются. При выполнении этого запроса через ADO.NET или через ADO, но  без параметров (передаю явные значения) - усечения не происходит.
    не знаю как в ADO.NET передается, а в ADO параметры передаются через варианты, а в варианте в дататайме миллисекунд нет... (было так во всяком случая, когда проверял. давно)

    > Такое же усечение наблюдается и для типа данных Decimal при передаче значения через параметр...
    а вот это неправда... если именно тип Decimal, хотя если денежный то допускаю, там действительно только 4 знака после запятой. посмотри если гдето внутри к currency приводится то...
    передавай через тип с плавающей запятой (double например).
  • ЮЮ © (14.03.08 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 © (14.03.08 10:36) [6]
    > Не лучше ли в триггере проставлять серверное время.
    на инсерт ка у тебя дальше? имхо не лучше, лучше тогда уж просто при создании таблицы поставить GetDate() полю как дефаултное значение.
  • ЮЮ © (14.03.08 10:43) [7]
    > на инсерт ка у тебя дальше?

    Не понял?

    >имхо не лучше
    А то что на часах клиенте можно накрутить любое время, конечно, лучше :)
  • Evgeny V © (14.03.08 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 © (14.03.08 11:05) [9]

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


    смотрю именно  select
  • sniknik © (14.03.08 11:06) [10]
    > Не понял?
    ну ты приводишь пример триггера

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

    > разница налицо между полями и логом.
    ошибка в программе?
    будь проще - пример запроса, тип поля, как вносишь, чем смотришь в чем разница. на пальцах. а то если разница например в 18 м знаке и для типа (участие наверняка есть) с плававающей запятой... вполне нормально.
  • Evgeny V © (14.03.08 11:14) [11]
    Пример запроса Insert я привел, а лог пишу значение параметра Format('%.18f',[par])  (но оно у меня то же в пришедшем файле),

    - при передаче через параметр разница как ты и сказал после 4 знака. При прямом запросе разницы нет для поля numeric и много меньше для поля DateTime - в 7 знаке, что в принципе устраивает
  • sniknik © (14.03.08 11:25) [12]
    > а лог пишу значение параметра Format('%.18f',[par])
    f - float, т.е. число с плавающей запятой. см. их свойства (на королевстве дельфи статью поищи)

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

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

    > и много меньше для поля DateTime - в 7 знаке
    DateTime как число? оригинально, ничего невозможного конечно тотже double, но хочу тебя огорчить, тут возможна разница не после запятой, а перед... точка отсчета "начала дней" в делфе и mssql не совпадает.
  • Evgeny V © (14.03.08 11:42) [13]

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

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


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

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


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


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


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


    Именно так оно в базе и происходит для запроса с параметрами.
  • sniknik © (14.03.08 11:49) [14]
    > Именно так оно в базе и происходит для запроса с параметрами.
    back
    sniknik ©   (14.03.08 10:24) [4]
    > передавай через тип с плавающей запятой (double например).
  • Evgeny V © (14.03.08 11:53) [15]
    sniknik ©   (14.03.08 11:49) [14]
    > DateTime как число? оригинально


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


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

    > Evgeny V ©   (14.03.08 10:58) [8]
  • sniknik © (14.03.08 11:55) [16]
    > Decimal
    в дельфи ближайший тип это BCD, но нормальной работы с ним в "базовых" компонентах нет... все через карренси. либо меняй тип поля, либо делай собственную обработку.
  • Evgeny V © (14.03.08 12:06) [17]

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

    Спасибо за помощь:-))
  • Anatoly Podgoretsky © (14.03.08 18:17) [18]
    > sniknik  (14.03.2008 11:25:12)  [12]

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

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

    --
  • piople (17.03.08 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 © (17.03.08 07:22) [20]

    > piople   (17.03.08 06:21) [19]

    Спасибо:-)
  • ANB (17.03.08 10:33) [21]

    > piople   (17.03.08 06:21) [19]

    +1. Еще неплохо на входе уже в запросе явно преобразовать в дату с маской - тогда настройки сервера и клиента никогда не повлияют.
  • Anatoly Podgoretsky © (18.03.08 04:31) [22]

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

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

    Поосторожнее с Интернетом, очень много грязи.
  • piople © (18.03.08 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 © (18.03.08 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 © (18.03.08 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 © (18.03.08 10:32) [26]

    > piople   (17.03.08 06:21) [19]



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


    Почты твоей нет, моя ася 246-886-495
 
Конференция "Базы" » ADO и параметры [D6, MSSQL]
Есть новые Нет новых   [134433   +22][b:0][p:0.002]