Forum Delphi.cz

Databáze => MS SQL => Téma založeno: jaja 12-04-2019, 15:38:38

Název: ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 12-04-2019, 15:38:38
Zdravím všechny,

při ukládání hodnoty datetime na SQL servru 2016 se neuloží do tabulky hodnota včetně milisekund,
respektive uložená časová známka v tabulce má vždy 0 milisekund:


Kód: Delphi [Vybrat]
  1.   with ADOQuery1 do
  2.   begin
  3.     SQL.Text:='select top(1) * from Table1';
  4.     Active:=True;
  5.     if not EOF then
  6.     begin
  7.       Edit;
  8.       FieldByName('HeartBeat').AsDateTime:=now;
  9.       Post;
  10.     end;
  11.     Active:=false;
  12.   end;

samozřejme zavolaný update command funguje včetně milisekund:

Kód: Delphi [Vybrat]
  1.   with ADOQuery1 do
  2.   begin
  3.     SQL.Text:='update Table1 set HeartBeat = getUTCDate()';
  4.     ExecSQL;
  5.   end;
  6.  

pokud existuje možnost jak uložit časovou známku do datetime sloupce včetně milisekund pomocí ADO pak předem dík

Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Delfin 12-04-2019, 21:43:10
ADO jsem nepouzil uz dlouho, navic ted nemam ani po ruce Delphi, nicmene mozna se toho problemu tyka toto vysvetleni (https://stackoverflow.com/a/14291452) (rika, ze Delphi implementace predava driveru pro sloupec typu DATETIME2[7] textovou hodnotu, jenz uz na strane klienta prijde o hodnotu milisekund). Od toho reseni se muze to Tve lisit v zavislosti na datovem typu daneho sloupce.
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 15-04-2019, 08:27:57
datový typ sloupce v tabulce je právě datetime a milisekundy jsou nulové u časové známky,
naopak pokud uložím časovou známku do sloupce typu nvarchar pak je uložená hodnota včetně milisekund,
bohužel potřebuju u stávejícího projektu (nelze měnit typy sloupců) změnit ukládaní včetně milisekund
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Delfin 15-04-2019, 09:26:26
datový typ sloupce v tabulce je právě datetime

To je v poradku. Tak to ma byt. Otazkou zustava, jak se hodnota TDateTime pres ADO predava DBMS. To Stack Overflow vlakno zminuje prave ztratu hodnoty milisekund pri predani hodnoty parametru na strane klienta. Nejde o zmenu typu sloupce. Nemam ted po ruce Delphi ani prostredi k testovani. O jake verze se jedna (Delphi, ADO, SQL Server)?
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 15-04-2019, 11:01:08
jedna se o Delphi 10.2 a SQL server 2016 + SP2, ADO verzi nevim jak zjistit, ale ADO bylo nainstalovano jako soucast Delphi 10.2,
zajimave je, ze cteni datetime hodnoty z databaze funguje vcetne milisekund (pokud jsou milisekundy nenulove diky update prikazu):

Kód: Delphi [Vybrat]
  1. var
  2.   myDate: TDateTime;
  3. begin
  4.   with ADOQuery1 do
  5.   begin
  6.     SQL.Text:='select top(1) * from Table1';
  7.     Active:=True;
  8.     if not EOF then
  9.       myDate:= FieldByName('HeartBeat').AsDateTime;
  10.     Active:=False;
  11.   end;
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Jirka 15-04-2019, 11:08:39
Citace
FieldByName('HeartBeat').AsDateTime:=now;
Máš ověřeno že "now"  skutečně vykazuje milisekundy ?
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 15-04-2019, 11:39:16
ano promenna v delphi obsahuje i milisekundy, ale hodnota v databazi ma milisekundy 0:

Kód: Delphi [Vybrat]
  1. var
  2.   myDate: TDateTime;
  3.   myYear, myMonth, myDay: Word;
  4.   myHour, myMin, mySec, myMilli: Word;
  5. begin
  6.   with ADOQuery1 do
  7.   begin
  8.     SQL.Text:='select top(1) * from Table1';
  9.     Active:=True;
  10.     if not EOF then
  11.     begin
  12.       Edit;
  13.       myDate:=now;
  14.       DecodeDateTime(myDate, myYear, myMonth, myDay, myHour, myMin, mySec, myMilli); //myMilli gets right millisedond value from myDate
  15.       FieldByName('HeartBeat').AsDateTime:=myDate;
  16.       Post;
  17.     end;
  18.     Active:=false;
  19.   end;

zkousel jsem v prirazeni misto AsDateTime pouzit AsSQLTimeStamp, ale i v tomto pripade se milisekundy neulozi:

Kód: Delphi [Vybrat]
  1. var dt: tsqltimestamp;
  2.       dt:= DateTimeToSQLTimeStamp(myDate);
  3.       FieldByName('HeartBeat').AsSQLTimeStamp:=dt;
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Delfin 15-04-2019, 11:48:27
A DataType objektu daneho pole je ftDateTime? Neni textoveho typu jak zminuje linkovane vlakno ze Stack Overflow pro sloupec DATETIME2? Paklize by tomu tak bylo, implicitni konverzi z datumocasu na text by doslo prave ke ztrate hodnoty milisekund.
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Jirka 15-04-2019, 12:00:55
Jen tak pro otestování  ..  masku píši z hlavy ..
FieldByName('HeartBeat').AsString:=FormatDateTime('DD.MM.YYYY hh:nn:ss.zzz', now)
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 15-04-2019, 13:04:39
Ano, editiovane pole je typu ftDateTime:

Kód: Delphi [Vybrat]
  1. var col: TFieldType;
  2. begin
  3.   with ADOQuery1 do
  4.   begin
  5.     SQL.Text:='select top(1) * from Table1';
  6.     Active:=True;
  7.     if not EOF then
  8.       col:=FieldByName('HeartBeat').DataType; //col value is ftDateTime
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: pf1957 15-04-2019, 13:12:15
A DataType objektu daneho pole je ftDateTime? Neni textoveho typu jak zminuje linkovane vlakno ze Stack Overflow pro sloupec DATETIME2? Paklize by tomu tak bylo, implicitni konverzi z datumocasu na text by doslo prave ke ztrate hodnoty milisekund.
Ja bych se podival, jestli pouzivas nativniho klienta, kdyz se pouzije nejaky ten obskurni universal SQL Server nebo jak se to jmenuje, tak ten prave nektere datove typy prasi pres stringy a leze z nej huhvi co. Nam fallback na takovy driver (nejnovejsi driver FireDAC neumi vyhledat) docela zamotal hlavu, nez jsme prisli, o co se jedna. Zkus mu klienta explicitne specifikovat https://docs.microsoft.com/en-us/sql/relational-databases/native-client/applications/using-ado-with-sql-server-native-client?view=sql-server-2017 (https://docs.microsoft.com/en-us/sql/relational-databases/native-client/applications/using-ado-with-sql-server-native-client?view=sql-server-2017)
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 15-04-2019, 13:12:28
prirazeni jako string ulozi casovou znamku, ale bez milisekund, resp. milisekundy jsou 0:
FieldByName('HeartBeat').AsString:=FormatDateTime('DD.MM.YYYY hh:nn:ss.zzz', now)

pokud zkusim jako Variant:
Kód: Delphi [Vybrat]
  1. var v: variant;
  2.       v:= variant(formatdatetime('dd.mm.yyyy hh:nn:ss.zzz',now));
  3.       FieldByName('HeartBeat').AsVariant:=v;
  4.  
pak vyjimka: EVariantTypeCastError with message'Could not convert variant of type (UnicodeString) into type (Date)'.
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: jaja 15-04-2019, 13:32:07
pouzity provider OLE DB:
Provider=SQLOLEDB.1;Persist Security Info=True;Initial Catalog=Database;Data Source=.\SQLEXPRESS
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Stanislav Hruška 15-04-2019, 13:58:00
Skúšal si tú hodnotu odovzdať do query cez parameter?
Název: Re:ADO datetime ukládání včetně milisekund
Přispěvatel: Michal 15-04-2019, 23:11:43
S tímhle jsem se kdysi dost natrápil a nebyl jsem schopen přijít na nic funkčního. Nakonec jsem použil zápis záznamu bez milisekund a následný update. Vím že to není čistý, nic jiného mi bohužel nezafungovalo.
Michal