![]() |
Datenbank: SQL-Server • Version: 2019 • Zugriff über: ADO
Int64 spinnt oder ich. HILFE!!!!
Eigentlich wollte ich nur IDs aus einer Datenbank übernehmen. Jetzt stellt sich raus, dass die alle falsch sind. Es ist auch egal, ob es eine SQL-Server-DB oder eine IBM-DB2-Datenbank ist. Die drei Zahlen im Beispiel sind identisch - nur nicht in der Ausgabe.
Delphi-Quellcode:
Und hier das Ergebnis in Memo1 - seht euch mal die letzten Ziffern an:
procedure TFMain.Button2Click(Sender: TObject);
var A, B: Int64; C: String; begin A:=-7978126718202166279; B:=Int64(DM.ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Value); C:=VarToStr(DM.ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Value); Memo1.Lines.Append('A: '+A.ToString); Memo1.Lines.Append('B: '+B.ToString); Memo1.Lines.Append('C: '+C); end; A: -7978126718202166279 B: -7978126718202166272 C: -7978126718202166279 |
AW: Int64 spinnt oder ich. HILFE!!!!
Wenn ich das richtig sehe dann haut nur B nicht hin.
Und da gibt es nur eine Option, rausbekommen was VarToStr anders macht als die Funktion Int64. Als was, als welcher Typ, kommt "bigint" in die Variante die dann in Int64 convertiert wird ...? |
AW: Int64 spinnt oder ich. HILFE!!!!
Hast du mal geprüft was das Feld für einen Delphi-Typ hat?
|
AW: Int64 spinnt oder ich. HILFE!!!!
Wenn man die Int64()-Funktion weglässt, sieht es leider genauso aus:
B:=DM.ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Value; |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Delphi-Quellcode:
Der Feldtyp passt schon...
if DM.ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Type_=adBigInt
then Memo1.Lines.Append('Treffer'); |
AW: Int64 spinnt oder ich. HILFE!!!!
adBigInt = 20 = varInt64. Das passt. Der Varianten Converter scheint ja auch zu funktionieren.
Also muss man anstatt direkter Zuweisung, was zu einem internen Cast auf Int64 zu führen scheint, VarToStr nutzen um dann wieder in Int64 zu konvertieren. Hast Du das mal probiert? Auch wenn es bescheuert ist:shock:. |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Delphi-Quellcode:
D:=StrToInt64(VarToStr(DM.ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Value));
|
AW: Int64 spinnt oder ich. HILFE!!!!
Kann man denn im Debugger nicht sehen was passiert?
|
AW: Int64 spinnt oder ich. HILFE!!!!
Ich habe nur Delphi 11 hier. Habe mich ein bisschen durch die Sourcen gegraben. Sieht so aus als wenn es 3 Methoden gibt mit denen intern umgewandelt wird. Interessant wäre es zu sehen was wirklich im fall des Fehlers genommen wird.
Aber, das ist eigentlich ein Fall für Emba, denn egal wie, es sollte immer der gleiche Wert rauskommen. |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
|
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
|
AW: Int64 spinnt oder ich. HILFE!!!!
Was passiert wenn man AsLargeInt nutzt?
![]() ![]() |
AW: Int64 spinnt oder ich. HILFE!!!!
Delphi-Quellcode:
function TLargeintField.GetValue(var Value: Largeint): Boolean;
begin Result := GetData(FIOBuffer); if Result then Value := TDBBitConverter.UnsafeInto<Int64>(FIOBuffer); end; |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
|
AW: Int64 spinnt oder ich. HILFE!!!!
Fehler ist jetzt gemeldet:
![]() |
AW: Int64 spinnt oder ich. HILFE!!!!
Wenn du nun irgendweche Vorstufen nutzt, dann glaube ich nicht das Emba das hierfür auch "nachimplementiert".
Kannst du nicht einen Helper implementieren, der diese AsLargInt (oder AsInt64) bereit stellt? |
AW: Int64 spinnt oder ich. HILFE!!!!
$914800050C81C3F9
$914800050C81C400 Die Art der Änderung sieht auch komisch aus. Was man sonst so für Probleme kennt, scheint es hier nicht zu sein (gedrehtes Bit, abgeschnittene Bytes, ...) Passiert es hier auch?
Delphi-Quellcode:
var A, B: Int64; C: String; V: Variant;
begin A := -7978126718202166279; V := DM.ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Value; B := Int64(V); C := VarToStr(V); Memo1.Lines.Append('A: ' + A.ToString); Memo1.Lines.Append('B: ' + B.ToString); Memo1.Lines.Append('C: ' + C); end; |
AW: Int64 spinnt oder ich. HILFE!!!!
Und mit "VarAsType(..., varInt64);" anstatt "Int64(...);" ?
|
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
A: -7978126718202166279 B: -7978126718202166272 C: -7978126718202166279 |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Delphi-Quellcode:
A: -7978126718202166279
var A, B, D, E: Int64; C: String; V: Variant;
begin A := -7978126718202166279; V := ADOCon.Execute('SELECT CAST(-7978126718202166279 as bigint)').Fields[0].Value; B := Int64(V); C := VarToStr(V); D := V; E := VarAsType(V, varInt64); Memo1.Lines.Append('A: ' + A.ToString); Memo1.Lines.Append('B: ' + B.ToString); Memo1.Lines.Append('C: ' + C); Memo1.Lines.Append('D: ' + D.ToString); Memo1.Lines.Append('E: ' + E.ToString); end; B: -7978126718202166272 C: -7978126718202166279 D: -7978126718202166272 E: -7978126718202166272 |
AW: Int64 spinnt oder ich. HILFE!!!!
noch eine winzige Erweiterung...
Delphi-Quellcode:
[edit] aktualisiert :duck:
Memo1.Lines.Append('Typ: ' + VarType(V).ToString + ' ' + VarTypeAsText(V));
Memo1.Lines.Append('Val: ' + TVarData(V).VInt64.ToString + ' ' + TVarData(V).VUInt64.ToString); Memo1.Lines.Append('Raw: ' + UIntPtr(TLargestVarData(TVarData(V).VAny^)._Reserved1).ToString + ' ' + UIntPtr(TLargestVarData(TVarData(V).VAny^)._Reserved2).ToString); var Tmp: string; for var i := 0 to 7{simplyunknown} do Tmp := Tmp + PAnsiChar(TVarData(V).VUnknown)[i]; Memo1.Lines.Append('Bin: ' + Tmp); |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Delphi-Quellcode:
Typ: Überlauf bei der Konvertierung einer Variante vom Typ (Decimal) in Typ (Integer)
try Memo1.Lines.Append('Typ: ' + VarType(V).ToString + ' ' + VarTypeAsText(V)); except on E:Exception do Memo1.Lines.Append('Typ: '+E.Message); end;
try Memo1.Lines.Append('Val: ' + IntToStr(TVarData(V).VUInt64)); except on E:Exception do Memo1.Lines.Append('Val: '+E.Message); end; try Memo1.Lines.Append('Raw: ' + UIntPtr(TLargestVarData(TVarData(V).VAny^)._Reserved1).ToString+ ' ' + UIntPtr(TLargestVarData(TVarData(V).VAny^)._Reserved2).ToString); except on E:Exception do Memo1.Lines.Append('Raw: '+E.Message); end; Val: 7978126718202166279 Raw: Zugriffsverletzung bei Adresse 008168A4 in Modul 'Project2.exe'. Lesen von Adresse F37E3C07 |
AW: Int64 spinnt oder ich. HILFE!!!!
Bin: Zugriffsverletzung bei Adresse 00A76992 in Modul 'Project2.exe'. Lesen von Adresse F37E3C07
|
AW: Int64 spinnt oder ich. HILFE!!!!
dann lass' erstmal den/die Letzten Zeilen weg.
Hatte das nur blind, nach gutem Wissen und Gewissen zusammengeklöppelt ... die Codevervollständigung hatte nichts gesagt, dass sie es falsch findet :stupid: Bei Typ hätte ich jetzt keinen Fehler erwartet :shock: Geh mal in deine Projektoptionen und schalte (vorübergehend) die Überlauf und Bereichsprüfung ab. (die ist seit ein paar Delphiversionen standardmäßig aktiv) Projektoptionen > Delphi-Compiler > Compilieren > Laufzeitfehler > Überlaufprüfung / Bereichsprüfung = off
Delphi-Quellcode:
Das Erste geht aber?
Memo1.Lines.Append('Typ: ' + VarType(V).ToString);
Memo1.Lines.Append('Typ: ' + VarTypeAsText(V)); |
AW: Int64 spinnt oder ich. HILFE!!!!
maaaaaaaaaaaaaaa ... der blöde VarType :wall:
OK, jetzt aber ... hoff' ich :oops:
Delphi-Quellcode:
Memo1.Lines.Append('Typ: ' + VarType(V).ToString + ' ' + VarTypeAsText(VarType(V)));
Memo1.Lines.Append('Val: ' + TVarData(V).VInt64.ToString + ' ' + TVarData(V).VUInt64.ToString); var Tmp: string; for var i := 0 to High(TVarData(V).RawData) do Tmp := Tmp + ' ' + TVarData(V).RawData[i].ToHexString; Memo1.Lines.Append('Bin: ' + Tmp); |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Typ: 14 Decimal Val: 7978126718202166279 7978126718202166279 Bin: 8000000E 00000000 F37E3C07 6EB7FFFA |
AW: Int64 spinnt oder ich. HILFE!!!!
Das ist schon ein klein bissl blöd.
Dezimal ist grade ein Variant-Typ, welcher an vielen Stellen als "unsupported" im Code zu finden ist. :vernupft: Aber so wie es aussieht, hätte ich vielerorts eine Exception erwartet, wenn darauf zugegriffen wird, anstatt einer falschen Rückgabe. mal sehn ... (heut abend / morgen ...) |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
// EDIT: Ach ja, und doof ist, dass man varDecimal nicht als Custom Type registrieren kann, obwohl Delphi den Typ nicht implementiert... Wenn da auch der Wert möglich wäre, wäre das eine Möglichkeit... Das könnte man recht einfach patchen, aber man müsste den Typ halt auch implementieren. Der Fehler hingegen passiert bei Microsoft in der Funktion VariantChangeTypeEx, die in VarToInt64ViaOS verwendet wird. Da könntest du höchstens im Feedback Hub einen Eintrag machen... Zitat:
|
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
|
AW: Int64 spinnt oder ich. HILFE!!!!
VarI8FromDec klingt nicht so schlecht
![]() wenigstens steht dort nichts von einem Fehler (auch sehr löblich die Fehler zumindest zu dokumentieren, anstatt sie zu beheben) ![]() |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Wenn man als Zieltyp wie ja auch gewünscht varInt64 angibt, funktioniert es korrekt. Warum das so gemacht wird, kann ich nicht nachvollziehen. Das halte ich dann doch für einen Bug in Delphi. |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
Und außerdem ist Decimal ja sowas wie ein Float, bzw. mehr wie Currency. (intelligent wäre es aber schon gewesen, wenn bei ganzzahl mit maximal 8 Byte (abzüglich 1 Bit) das vt_i8 anstatt vt_r8 genommen würde) |
AW: Int64 spinnt oder ich. HILFE!!!!
Zitat:
![]() |
AW: Int64 spinnt oder ich. HILFE!!!!
Der gemeldete Bug wurde in Delphi 12.3 bereits behoben. :thumb:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz