Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Welches DateTime Format schluckt jede Datenbank? (https://www.delphipraxis.net/205506-welches-datetime-format-schluckt-jede-datenbank.html)

t2000 17. Sep 2020 14:39

Datenbank: alle • Version: 1 • Zugriff über: x

Welches DateTime Format schluckt jede Datenbank?
 
Hallo,

wie der Titel schon sagt, welches DateTime Format schluckt jede Datenbank?
Ich habe für ein Programm eine kleine Installationsdatei, in der auch SQL-Befehle stehen. In diesen Befehlen taucht auch ein Datum/Uhrzeit auf.
Gibt es eine Norm, mit der ich ein ==> INSERT INTO Tabelle (Feld1, Feld2, Feld3) VALUES (12, 'Ein Text', '25.04.2020 15:33:44') <== machen kann?
'2020-04-25T10:58:00.000' vielleicht? ISO-Norm

Gruß Thomas

Der schöne Günther 17. Sep 2020 14:44

AW: Welches DateTime Format schluckt jede Datenbank?
 
Um Gottes Willen bitte keine Strings zusammenbasteln sondern mit Parametern.

Dann kommt in den Parameter einfach deine DateTime-Variable und du musst dir keinen Kopf machen.

Vor allem wegen Dingen wie "SQL Injection" sollte man auf keinen Fall Strings zusammenbauen sondern mit Parametern arbeiten. Hier einmal ein anschauliches und unterhaltsames Beispiel:
https://xkcd.com/327/

t2000 17. Sep 2020 14:52

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1473748)
Um Gottes Willen bitte keine Strings zusammenbasteln sondern mit Parametern.

Dann kommt in den Parameter einfach deine DateTime-Variable und du musst dir keinen Kopf machen.

Vor allem wegen Dingen wie "SQL Injection" sollte man auf keinen Fall Strings zusammenbauen sondern mit Parametern arbeiten. Hier einmal ein anschauliches und unterhaltsames Beispiel:
https://xkcd.com/327/

Nein, nein. Alles Bekannt.
Es geht hier nicht um Delphi, sondern um ein ganz kleines Importskript, das bei der Installation der Software vorher eingespielt werden soll.

Quasi direkt nach dem CREATE TABLE ...

Delphi.Narium 17. Sep 2020 15:06

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1473748)
Um Gottes Willen bitte keine Strings zusammenbasteln sondern mit Parametern.

Dann kommt in den Parameter einfach deine DateTime-Variable und du musst dir keinen Kopf machen.

Vor allem wegen Dingen wie "SQL Injection" sollte man auf keinen Fall Strings zusammenbauen sondern mit Parametern arbeiten. Hier einmal ein anschauliches und unterhaltsames Beispiel:
https://xkcd.com/327/

Das funktioniert aber nicht in 'ner Installationsdatei, die u. a. auch Insertstatements enthält.

Man baut nicht jede Datenbank mit 'nem Delphiprogramm auf, in dem man Parameter nutzen kann. Es gibt auch immer noch Installationsscripte für Datenbanken, die neben den Createstatements für die Tabellen, Indizies, ..., auch Insertstatments für die erstmalige Befüllung enthalten.

Und in dem Zusammenhang ist die Frage nach dem zu verwendenden Datumsformat durchaus berechtigt.

Geht dashier bei allen Datenbanken? W3Schools - SQL Working With Dates

Und nu: Schauen, was alle anderen ggfls. zu verwendenden Datenbanken so unterstützen.

Hab' auf die Schnelle keine Seite gefunden, die da mal 'nen "globalgalaktischen" Überblick zur Verfügung stellt.

HeZa 17. Sep 2020 15:25

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1473750)
...Geht dashier bei allen Datenbanken? W3Schools - SQL Working With Dates...

Ein Datum mit Uhrzeit im ISO-Format sollten eigentlich viele Datenbanken schlucken können (z.B. 2020-09-17 16:24:33).

jobo 17. Sep 2020 17:39

AW: Welches DateTime Format schluckt jede Datenbank?
 
Alle? Das ist schon eine krasse Frage.

Auch wenn DB vielleicht ISO Norm Formatierungen abdecken können, machen sie es gerne unterschiedlich. Also per Funktion die überall anders genannt wird. Ich bin ehrlich gesagt noch nicht drauf gekommen, sowas zu versuchen. Mein Tipp wäre, dass ein Datum entsprechend der Windows Datumseinstellungen als bloßer Text formatiert am besten geht. Das Script würde dann mit impliziter Typkonvertierung beim Datum arbeiten.
Das Problem daran ist natürlich sofort klar, niemand weiß vorher, wie alle Nutzer ihre Windows Datumsformatierung eingestellt haben.

Wenn man das durchspielt, landet man irgendwann bei einem Importprogramm, das wie bereits beschrieben das Typhandling selbst macht und ein festes, proprietäres Datum vorgesetzt bekommt.

Delphi.Narium 17. Sep 2020 18:19

AW: Welches DateTime Format schluckt jede Datenbank?
 
Deshalb weiter oben auch meine Frage
Zitat:

Geht dashier bei allen Datenbanken?
Zitat:

Zitat von HeZa (Beitrag 1473754)
Ein Datum mit Uhrzeit im ISO-Format sollten eigentlich viele Datenbanken schlucken können (z.B. 2020-09-17 16:24:33).

Das sollte eigentlich wäre eine wünschenswerte Annahme, aber ich gehe mal davon aus, dass das leider wohl für die nächsten Jahr(zehnt)e Wunschdenken bleibt.

FireBird kennt keinen Datentypen DateTime, sondern nur Date, Time und Timestamp.

Postgres kennt wohl auch Date, Time und Timestamp, wobei der Timestamp von PostGres 14stellig ist und bis zu einer Auflösung von einer Microsekunde geht. Bei FireBird ist es jedoch ein aus zwei 32-bittigen Teilen bestehendes Konstrukt, für die getrennte Aufnahme von Datum und Uhrzeit, mit 'ner Auflösung bis zur einer Millisekunde.

Oracle hat sowas wie Date und Timestamp.
Timestamp gibt es mit oder ohne Zeitzone oder auch lokaler Zeitzone.

Je nach gewähltem Typ könnte man daher bei 'nem
Code:
INSERT INTO Tabelle (Feld1, Feld2, Feld3) VALUES (12, 'Ein Text', '25.04.2020 15:33:44')
beim Auslesen durchaus was unterschiedliches bekommen.

Daher ist Timestamp <> Timestamp :-(

Bei Access ist DateTime 8bittig vom Jahr 100 bis zum Jahr 9999.

MySQL kennt DateTime und Timestamp, sie können beide Datum und Uhrzeit enthalten, haben aber unterschiedliche "Zeitspannen" für gültige Werte. Bei 'nem Insert muss man da damit rechnen, dass der Wert aus Values mit der gerade im System eingestellten Zeitzone Richtung UTC "konvertiert" wird.

Man sollte beim Insert die Zeitzone also auch noch berücksichtigen ...

Und es wird bestimmt auch noch weitere Datenbanken geben, die was eigenes haben und Systemeinstellungen auf eigene Weise berücksichtigen, ...

Von daher befürchte ich: Die Frage
Zitat:

Welches DateTime Format schluckt jede Datenbank?
kann man nicht ruhigen Gewissens mit einer einfachen Datumsformatangabe beantworten.

HeZa 17. Sep 2020 18:27

AW: Welches DateTime Format schluckt jede Datenbank?
 
Er fragte nach der Datums/Zeit-Formatierung. Den richtigen Datentyp zu wählen überlasse ich dem Fragesteller. :lol:

himitsu 17. Sep 2020 20:33

AW: Welches DateTime Format schluckt jede Datenbank?
 
Ja, im Delphi den Typ in DateTime/TimeStamp/... konvertieren und die DB-Komponenten es machen lassen ist das Einfachste und Universellste.

In diesem Fall mach es dir einfach und füge eine Funktion ein
oder arbeite bei den Datumstypen mit "eigenen" VARCHAR->Datumstyp-AutoCasts (Bei Google suchenCREATE CAST o.Ä.).
SQL-Code:
INSERT INTO Tabelle (Feld1, Feld2, Feld3) VALUES (12, 'Ein Text', DeineFunktion('25.04.2020 15:33:44'))

Alles was nicht allgemeingültig ist, wird mit jeweils Manuellen und AutoCasts versehen und lässt sich so zentral anpassen, an nur einer Stelle.

Oder mache den Imports/Export diese Typen als VARCHAR, wo dann, anschließend an den Import, diese Spalten erst mit jeweils passenden Methoden konvertiert/umkopiert werden.


Ja, Postgres kennt Vieles und Alles auch nochmal mit frei definierbarem Rundungsverhalten (quasi mit änderbarer Bittigkeit)
und dann auch nochmal mit oder ohne TimeZone, welche im Typ gespeichert/verwaltet werden könnte.
Dazu verstehen die vorhandenen AutoCasts auch noch mehrere Text-Formate. (Datenbank/Tabelle/Feld auf Deutsch versteht ein deutsches Datumsformat und auch unterschiedliche ISO-Formate, was aber z.B. in einer englischen Datenbank importiert knallen dürfte)

t2000 18. Sep 2020 08:05

AW: Welches DateTime Format schluckt jede Datenbank?
 
Das habe ich fast befürchtet. Keinerlei allgemeingültige Regel.
Ich werde wahrscheinlich das Installationsskript für die (für uns) zur Zeit wichtigsten Datenbanken (PostgreSQL, MSSQL, evtl. SQLite, Interbase) für Standardnutzer in Deutschland anpassen. Da komme ich mit einer einzigen Formatierung klar.
Solange ich nicht Software für das Ausland produziere kann ich die wenigen Ausnahmefälle wohl von Hand bearbeiten.
MSSQL macht zum Beispiel beim Generieren von Importskripten immer sowas: INSERT ... VALUES(12, 'abc', cast('25.04.2020 14:55:22' as DateTime2))
wobei ja dann der Datentyp bekannt sein müssete :(

dummzeuch 18. Sep 2020 08:35

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von HeZa (Beitrag 1473754)
Zitat:

Zitat von Delphi.Narium (Beitrag 1473750)
...Geht dashier bei allen Datenbanken? W3Schools - SQL Working With Dates...

Ein Datum mit Uhrzeit im ISO-Format sollten eigentlich viele Datenbanken schlucken können (z.B. 2020-09-17 16:24:33).

Oha, das ist aber optimistisch gedacht.

Selbst aktuelle Datenbanken dürften da noch Probleme machen, da kommt es ggf. darauf an, was der Admin eingestellt hat.

z.B. kennt MS-SQL auch so völlig bescheuerte Formate wie '09-17-20', was man natürlich auf den ersten Blick als amerikanisches Datumsformat (MM/TT/YY) mit '-' statt '/' erkennt. Quasi das schlimmste, was man sich ausdenken kann. Und glaube bloß nicht, dass das keiner so einstellt (Woher wüsste ich das sonst?)

TigerLilly 18. Sep 2020 08:54

AW: Welches DateTime Format schluckt jede Datenbank?
 
"Jede" sind ziemlich viele :-)
Aber die meisten sollte schon gehen.

SQL 92 ist der Standard, an den die meisten Systeme sich halten:
https://www.ibphoenix.com/resources/...design/doc_169

haentschman 18. Sep 2020 09:02

AW: Welches DateTime Format schluckt jede Datenbank?
 
Moin...8-)
Zitat:

MSSQL macht zum Beispiel beim Generieren von Importskripten immer sowas: INSERT ... VALUES(12, 'abc', cast('25.04.2020 14:55:22' as DateTime2))
Das ganze verstehe ich nicht. Die Datenbank bekommt immer einen TDateTime(Double) Wert... Damit ist das Thema Datenbank erledigt. Ob das eine Meier-Müller DB ist, TDateTime ist TDateTime.
Zitat:

sondern um ein ganz kleines Importskript
Der Importer muß das Format erkennen und umwandeln in TDateTime. :warn:

...oder habe ich was verpaßt? :wink:

mkinzler 18. Sep 2020 09:06

AW: Welches DateTime Format schluckt jede Datenbank?
 
Wenn es über ein (Delphi-)Programm geht dann ja. Es scheint hier aber um die Möglichkeit zu gehen, Skripte zur Anlage direkt auf die DB auszuführen.

haentschman 18. Sep 2020 09:12

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Es scheint hier aber um die Möglichkeit zu gehen, Skripte zur Anlage direkt auf die DB auszuführen.
...ok. Könnte man sich nicht im Setup ein Konsolen Programm aufrufen, was die DB Einträge macht. SQL mit Parametern laden, rein in Query...fertsch. :stupid:

HolgerX 18. Sep 2020 11:11

AW: Welches DateTime Format schluckt jede Datenbank?
 
Hmm..

Es ist eigentlich NIE gut ein Datum als String in einem SQL Befehl anzugeben.
Ob und wie der String dann in ein Datum gewandelt wird hängt nicht nur vom verwendeten Datenbanksystem ab, sondern auch z.B. von der installierten Sprache des Datenbankserver.

Ein MS SQL-Server interpretiert ein Datum nach der installierten Sprache unterschiedlich. So kann es dazu kommen, dass Monat und Tag vertauscht werden.

Somit musst Du wohl SQL-Scripte angepasst für das Datenbanksystem bereitstellen.
Für SQL-Server z.B. durch Verwendung von convert:

convert(datetime,'2020.05.15 07:00:00',120)

Die 120 gibt bei der Konvertierung des Strings in das Datetime dann dessen Format an.
So ist sichergestellt, dass das Datum auch bei fremdsprachigen SQL-Servern korrekt übernommen wird.

generic 18. Sep 2020 11:49

AW: Welches DateTime Format schluckt jede Datenbank?
 
Es gibt noch das ODBC Date-Format:
Code:
{d'2020-12-30'}

update meineTabelle set datumsFeld={d'2020-12-30'}
das versteht u.a. der MSSQL
https://docs.microsoft.com/en-us/sql...l-server-ver15

und MYSQL
https://dev.mysql.com/doc/refman/8.0...-literals.html
.


Anstelle von d "datum" kann auch t "time" oder auch ts "timestamp" genutzt werden.

Rollo62 18. Sep 2020 12:25

AW: Welches DateTime Format schluckt jede Datenbank?
 
Es bestünde noch die Möglichkeit YY, MM, DD, HH, NN, SS alle in separate numerische Felder zu legen.
Das sollte jede DB hinbekommen, muss man dann aber auch zerlegen/zusammensetzen,
sollte aber auf jedenfall überall sicher sein.

generic 18. Sep 2020 12:38

AW: Welches DateTime Format schluckt jede Datenbank?
 
So wie ich Thomas verstehe, möchte er *ein* SQL-Skript erstellen, welches die DB unabhängig vom verwendeten Server anlegen kann.
Es natürlich einfacher als Skripte für jedes System pflegen zu müssen.

Bernhard Geyer 18. Sep 2020 12:44

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von Rollo62 (Beitrag 1473805)
Es bestünde noch die Möglichkeit YY, MM, DD, HH, NN, SS alle in separate numerische Felder zu legen.
Das sollte jede DB hinbekommen, muss man dann aber auch zerlegen/zusammensetzen,
sollte aber auf jedenfall überall sicher sein.

Und dann auf alle schönen SQL-Funktionen verzichten die mit Datum/Uhrzeitangaben rechnen können.
Das wäre mir persönlich doch ein zu großer Nachteil.

Bei uns nutzen String und das ISO-Format.
Dann geht immerhin Sortierung "out of the box" korrekt.

IBExpert 18. Sep 2020 15:13

AW: Welches DateTime Format schluckt jede Datenbank?
 
wenn ich irgendwelche abstrusen strings bekommen würde und diese in gültige timestamps umwandeln sollte,
dann wäre mein weg mit firebird 3, diese beim Import durch eine selbstgeschriebene Stored Function zu schicken
so das der Insert in etwa so aussieht:

insert into tbl(id,ts) values(123, MeineFunktion('heute'));
insert into tbl(id,ts) values(124, MeineFunktion('jetzt'));
insert into tbl(id,ts) values(125, MeineFunktion('Neujahr 2020'));

etc

create or alter function MeineFunktion
(val varchar(80))
returns timestamp
as
declare variable res timestamp;
begin
if (val='heute') then res=current_date;
else
if (val='jetzt') then res=current_timestamp;
else
if (val containing 'Neujahr') then
begin
res=cast(replace(val,'Neujahr ','1.1.') as date);
end
else
res=val;
return res;
end

die üblichen formate kann firebird relativ gut, aber meine Erfahrung basiert zum Beispiel auf Import
von EMail Inhalten, wo der sender mal gerne schwachsinn einbaut, unter anderem kam da auch schon
utc+48 als Zeitzone oder 25:10 als Uhrzeit usw.

iIm falle einer exception kann man dann mit einer when any anweisung den ungültigen string
in eine extra protokoll tabelle packen und seine routine nach und nach verbessern.

ist aber vielleicht nicht das was du suchst, aber ein weg, das geschilderte Problem mit fb
zu lösen

Redeemer 19. Sep 2020 19:33

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von HeZa (Beitrag 1473754)
Zitat:

Zitat von Delphi.Narium (Beitrag 1473750)
...Geht dashier bei allen Datenbanken? W3Schools - SQL Working With Dates...

Ein Datum mit Uhrzeit im ISO-Format sollten eigentlich viele Datenbanken schlucken können (z.B. 2020-09-17 16:24:33).

Das Beispiel geht mit MSSQL nicht, denn ein Jahr hat keine 17 Monate. MSSQL akzeptiert das Beispiel ohne Striche als gültiges Datum, MySQL aber nicht. Was bei beiden geht, ist '2020-09-17T16:24:33'.

Bevor das jemand fragt: CURRENT_TIMESTAMP ist die einzige von MySQL und MSSQL akzeptierte Schreibweise für Jetzt.

generic 20. Sep 2020 00:20

AW: Welches DateTime Format schluckt jede Datenbank?
 
Zitat:

Zitat von Redeemer (Beitrag 1473880)
Zitat:

Zitat von HeZa (Beitrag 1473754)

Ein Datum mit Uhrzeit im ISO-Format sollten eigentlich viele Datenbanken schlucken können (z.B. 2020-09-17 16:24:33).

Das Beispiel geht mit MSSQL nicht, denn ein Jahr hat keine 17 Monate. MSSQL akzeptiert das Beispiel ohne Striche als gültiges Datum, MySQL aber nicht. Was bei beiden geht, ist '2020-09-17T16:24:33'.

Bevor das jemand fragt: CURRENT_TIMESTAMP ist die einzige von MySQL und MSSQL akzeptierte Schreibweise für Jetzt.

Also als String angegeben greifen die Ländereinstellungen bzw. die set FMT Einstellung bei dem MSSQL.
Daher gibt das als ODBC String an, wie ich oben bereits geschrieben hatte.

Code:
{ts'2020-09-17 16:24:33'}


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz