Datenkonvertierung mit großen Zahlen
Moderator: Moderatoren
Datenkonvertierung mit großen Zahlen
Hallo,
nach langer Zeit habe ich noch mal mein XBase 1.80 mit SQL-Express ausgegraben, da ich ein Interface zwischen 2 MS-SQL 2008 Datenbanken schaffen muß. In der SQL-Datenbank gibt es das Feld ObjectID, das als numeric 18, 0 definiert ist. Genau dieses Feld bereitet mit Probleme, da es nicht richtig eingelesen wird.
In der Datenbank beinhaltet das Feld den Wert 186385493536103871. Lasse ich mir den Wert in xBase anzeigen, so sehe ich die Zahl 186385493536103900. Es handelt sich nicht um ein Anzeigeproblem, denn ein Variablenvergleich funktioniert auch nicht. Versuchsweise habe ich auf die Variable 0.1 addiert um über eine Dezimalzahl eine höhere Genauigkeit zu erreichen aber das führt nur zum Ergebnis 186385493536103900.0. Eigentlich sollte xBase doch mit so großen Zahlen umgehen können, denn lt. Handbuch können numerische Werte von 10 hoch 308 bis 10 hoch -308 gehen.
Hat jemand von Euch eine Idee?
Danke und Gruß
Andreas
nach langer Zeit habe ich noch mal mein XBase 1.80 mit SQL-Express ausgegraben, da ich ein Interface zwischen 2 MS-SQL 2008 Datenbanken schaffen muß. In der SQL-Datenbank gibt es das Feld ObjectID, das als numeric 18, 0 definiert ist. Genau dieses Feld bereitet mit Probleme, da es nicht richtig eingelesen wird.
In der Datenbank beinhaltet das Feld den Wert 186385493536103871. Lasse ich mir den Wert in xBase anzeigen, so sehe ich die Zahl 186385493536103900. Es handelt sich nicht um ein Anzeigeproblem, denn ein Variablenvergleich funktioniert auch nicht. Versuchsweise habe ich auf die Variable 0.1 addiert um über eine Dezimalzahl eine höhere Genauigkeit zu erreichen aber das führt nur zum Ergebnis 186385493536103900.0. Eigentlich sollte xBase doch mit so großen Zahlen umgehen können, denn lt. Handbuch können numerische Werte von 10 hoch 308 bis 10 hoch -308 gehen.
Hat jemand von Euch eine Idee?
Danke und Gruß
Andreas
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Hallo,
ich habe folgendes getestet (xpp 1.90.355):
und erhalte dieses Ergebnis:
gerade am letzten N sieht man, dass nX und nZ eigentlich ungleich sein müssten, es aber in der Variable nicht sind !
In der Dokumentation steht:
Eventuell kann ja eine Supportanfrage bei Alaska mehr Klarheit bringen, aber ich vermute dein Datentyp braucht eine 64 Bit INTEGER - und die haben wir in Xbase++ nicht.
ich habe folgendes getestet (xpp 1.90.355):
Code: Alles auswählen
#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
procedure main()
local nWert, nX, nZ
nWert := 123456789012345678
nX := nWert+1
nZ := nX-1
cls
? nWert
? nX
? nZ
? str(nWert,18,0)
? str(nX,18,0)
? str(nZ,18,0)
? "nWert == nZ ?",nWert == nZ, nX # nZ
wait
return
Code: Alles auswählen
123456789012345700
123456789012345700
123456789012345700
123456789012345700
123456789012345700
123456789012345700
nWert == nZ ? J N
Press any key to continue...
In der Dokumentation steht:
somit akzeptiert die Variable zwar den Wertebereich, aber mehr als 16 Vorkommastellen können nicht wirklich verarbeitet werden.Die Anzeige numerischer Werte am Bildschirm ist nur bis auf 16 Vorkommastellen und 15 Nachkommastellen garantiert, so daß numerische Werte mit maximal 31 Ziffern plus Dezimalkomma angezeigt werden können. Bei Zahlen mit mehr Vor- oder Nachkommastellen werden bei der Anzeige gegebenenfalls Sterne * oder Nullen 0 angezeigt.
Wenn ein numerischer Wert in einer Feldvariable (DBF-Datei) gespeichert wird, erfolgt eine Transformation des Werts zu einem Format, das angezeigt werden kann. Aus diesem Grund können numerische Werte in Feldvariablen einer DBF-Datei mit einer maximalen Genauigkeit von 16 Vorkommastellen und 15 Nachkommastellen gespeichert werden.
Eventuell kann ja eine Supportanfrage bei Alaska mehr Klarheit bringen, aber ich vermute dein Datentyp braucht eine 64 Bit INTEGER - und die haben wir in Xbase++ nicht.
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Mein Tipp, auf 16 Stellen umstellen, soviele Objekte kann es gar nicht geben, dass man mehr als 16 Stellen benötigt - oder Sprache wechseln
Mit 16 Stellen funktioniert das auch mit Xbase++ prima.
andere Sprachen ...
Mein PowerBasic Compiler gibt an, dass eine (8Byte-64bit) QUAD INTEGER 18 Stellen verarbeiten kann.
Andere Namen: C/C++ LARGE_INTEGER, Delphi int64 und in WinDev unsigned int on 8 bytes
Ergebnis:
Fehlerfrei !
Im Handbuch von PowerBasic steht auch, dass das bei uns verwendete Zahlenformat nur für 16 Stellen gut ist.
Wer 18 will, braucht eine 10 Byte Fließkommazahl (Extended-precision - 10 bytes ... offer 18 digits of precision)
WinDev nennt diese Currency
Ob allerdings die ODBC Datenbank-Schnittstelle diese großen Zahlen auch verarbeiten kann ?
Code: Alles auswählen
#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
procedure main()
local nWert, nX, nZ
nWert := 1234567890123456
nX := nWert+1
nZ := nX-1
cls
? nWert
? nX
? nZ
? str(nWert,16,0)
? str(nX,16,0)
? str(nZ,16,0)
? "nWert == nZ ?",nWert == nZ, nX # nZ
wait
return
Code: Alles auswählen
1234567890123456
1234567890123457
1234567890123456
1234567890123456
1234567890123457
1234567890123456
nWert == nZ ? J J
Press any key to continue...
andere Sprachen ...
Mein PowerBasic Compiler gibt an, dass eine (8Byte-64bit) QUAD INTEGER 18 Stellen verarbeiten kann.
Andere Namen: C/C++ LARGE_INTEGER, Delphi int64 und in WinDev unsigned int on 8 bytes
Code: Alles auswählen
' PowerBasic
#COMPILE EXE
#DIM ALL
FUNCTION PBMAIN () AS LONG
LOCAL nWert, nX, nZ AS QUAD
nWert = 123456789012345678
nX = nWert+1
nZ = nX-1
CLS
? "Anzeige ohne STR$() geht nicht !"
? nWert
? nX
? nZ
? STR$(nWert,18)
? STR$(nX,18)
? STR$(nZ,18)
? "nWert == nZ ?",nWert = nZ, nX <> nZ
WAITKEY$
END FUNCTION
Code: Alles auswählen
Anzeige ohne STR$() geht nicht !
1.23456789012346E+17
1.23456789012346E+17
1.23456789012346E+17
Anzeige mit STR$(x,18) geht es !
123456789012345678
123456789012345679
123456789012345678
nWert == nZ ? -1 -1
Im Handbuch von PowerBasic steht auch, dass das bei uns verwendete Zahlenformat nur für 16 Stellen gut ist.
Wer 18 will, braucht eine 10 Byte Fließkommazahl (Extended-precision - 10 bytes ... offer 18 digits of precision)
WinDev nennt diese Currency
Code: Alles auswählen
// WinDev - macht alles richtig ;-)
Wert1, nWert2, nWert3 is unsigned int on 8 bytes
nWert1 = 123456789012345678
nWert2 = nWert1 + 1
nWert3 = nWert2 - 1
EDT_Integer1 = nWert1
EDT_Integer2 = nWert2
EDT_Integer3 = nWert3
IF nWert3 = nWert1 AND nWert3 <> nWert2 THEN
Info("Super, alles erkannt")
ELSE
Info("Schade, falscher Schluss")
END
Gruß
Hubert
Hubert
Re: Datenkonvertierung mit großen Zahlen
Hallo Hubert,
danke für Deinern Test. Ich hatte die Doku tatsächlich auf die Anzeigefunktionalität bezogen und nicht auf die Verarbeitung in der Variable. Eine Supportanfrage bei Alaska hilft mir nicht weiter, denn zum einen habe ich mit meiner alten Version keinen Support mehr und bis (wenn überhaupt) eine Lösung kommt ist es für mich schon zu spät, denn ich bräuchte die Lösung schon gestern.
Gruß
Andreas
danke für Deinern Test. Ich hatte die Doku tatsächlich auf die Anzeigefunktionalität bezogen und nicht auf die Verarbeitung in der Variable. Eine Supportanfrage bei Alaska hilft mir nicht weiter, denn zum einen habe ich mit meiner alten Version keinen Support mehr und bis (wenn überhaupt) eine Lösung kommt ist es für mich schon zu spät, denn ich bräuchte die Lösung schon gestern.
Gruß
Andreas
Re: Datenkonvertierung mit großen Zahlen
Hallo Hubert,
der ODBC-Treiber macht an dieser Stellen keinen Ärger. Die Daten lassen sich einwandfrei in Excel oder Access importieren. Auf 16 Stellen reduzieren kann ich leider auch nicht, da es sich um die Datenbank eines Drittanbieters handelt. Da ist nichts zu machen. Bleibt die andere Sprache und da tue ich mich schwer, denn mit xBase kommt man so leicht ans Ziel und schnell ist es auch noch, wenn es um das lesen, schreiben und modifizieren von Daten geht.
Da es mit xBase ja nicht so recht weiter geht habe ich vor geraumer Zeit mal mit dem Visual Studio experementiert. Für mich ein einziger Krampf. In der Zeit wo ich mit Visual Studio 10000 Datensätze gelesen habe, hätte ich mit xBase hunderttausende verarbeitet.
Gruß
Andreas
der ODBC-Treiber macht an dieser Stellen keinen Ärger. Die Daten lassen sich einwandfrei in Excel oder Access importieren. Auf 16 Stellen reduzieren kann ich leider auch nicht, da es sich um die Datenbank eines Drittanbieters handelt. Da ist nichts zu machen. Bleibt die andere Sprache und da tue ich mich schwer, denn mit xBase kommt man so leicht ans Ziel und schnell ist es auch noch, wenn es um das lesen, schreiben und modifizieren von Daten geht.
Da es mit xBase ja nicht so recht weiter geht habe ich vor geraumer Zeit mal mit dem Visual Studio experementiert. Für mich ein einziger Krampf. In der Zeit wo ich mit Visual Studio 10000 Datensätze gelesen habe, hätte ich mit xBase hunderttausende verarbeitet.
Gruß
Andreas
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Hi,
was genau muss den dein Job in diesem Falle erledigen ?
Die Daten per ODBC z.B. mit PowerBasic zu laden und verarbeitet in eine andere zu stecken ist nicht so viel Aufwand und
mit dem PBCC kann man commandozeilen Programme schreiben.
Ein solches könnte dein Xbase++ Verwaltungsprogramm per runshell starten ... es kommt halt auf die Komplexität an.
Eine neue Sprache lernen um ein komplettes Programm zu schreiben ist schon hart.
was genau muss den dein Job in diesem Falle erledigen ?
Die Daten per ODBC z.B. mit PowerBasic zu laden und verarbeitet in eine andere zu stecken ist nicht so viel Aufwand und
mit dem PBCC kann man commandozeilen Programme schreiben.
Ein solches könnte dein Xbase++ Verwaltungsprogramm per runshell starten ... es kommt halt auf die Komplexität an.
Eine neue Sprache lernen um ein komplettes Programm zu schreiben ist schon hart.
Gruß
Hubert
Hubert
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2518
- Registriert: Mi, 28. Jul 2010 17:16
- Hat sich bedankt: 12 Mal
- Danksagung erhalten: 77 Mal
Re: Datenkonvertierung mit großen Zahlen
Hi,
kannst du den Wert zum speichern nicht in 2 Variablen aufteilen und dann in 2 Datenfelder speichern? (Hi / Low Wert)
Gruss Carlo
kannst du den Wert zum speichern nicht in 2 Variablen aufteilen und dann in 2 Datenfelder speichern? (Hi / Low Wert)
Gruss Carlo
Valar Morghulis
Gruss Carlo
Gruss Carlo
- AUGE_OHR
- Marvin
- Beiträge: 12910
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Datenkonvertierung mit großen Zahlen
wo steht das im Handbuch ?ath hat geschrieben:Eigentlich sollte xBase doch mit so großen Zahlen umgehen können, denn lt. Handbuch können numerische Werte von 10 hoch 308 bis 10 hoch -308 gehen.
das ist die DBF Spezifkation !DATA Component
Specifications for DBF files
...
Numeric values Fields contain max. 19 bytes, including
decimal point and negative signed prefix
mit solch grossen Zahlen habe ich noch nicht gearbeitet, wenn dann mit BIN2U / U2BIN.
gruss by OHR
Jimmy
Jimmy
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2470
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Würden die richtigen Werte zurückgegeben, wenn Du einfach intern für Dich das Teil als Zahl mit
Nachkommastellen betrachtest ?
Beispiel:
sql-Wert / 10000
Dann hättest Du intern 4 Nachkommastellen, aber nur 14 davor ?
Nachkommastellen betrachtest ?
Beispiel:
sql-Wert / 10000
Dann hättest Du intern 4 Nachkommastellen, aber nur 14 davor ?
Gruß
Klaus
Klaus
Re: Datenkonvertierung mit großen Zahlen
Hallo Carlo,ramses hat geschrieben:kannst du den Wert zum speichern nicht in 2 Variablen aufteilen und dann in 2 Datenfelder speichern? (Hi / Low Wert)
das geht leider nicht, da die Anweisung nObjectID := oCursor:fieldget("objectid") bereits den falschen Wert liefert. Für eine Aufteilung müßte ich erstmal den Wert korrekt einlesen können und an der Datenbank (da Fremdprodukt) kann ich nichts ändern.
Gruß
Andreas
Re: Datenkonvertierung mit großen Zahlen
wo steht das im Handbuch ?AUGE_OHR hat geschrieben:ath hat geschrieben:Eigentlich sollte xBase doch mit so großen Zahlen umgehen können, denn lt. Handbuch können numerische Werte von 10 hoch 308 bis 10 hoch -308 gehen.
Hi Jimmy,
suche in der Hilfe-Datei nach numerisch. Dann findest Du dies:
...Numerische Werte werden bei Xbase++ im IEEE 64-Bit Format für Fließkommazahlen gehandhabt. Daraus ergibt sich für Berechnungen ein Zahlenbereich von 10 hoch +308 bis 10 hoch -308. Die binäre Repräsentation von Fließkommazahlen erlaubt eine Rechengenauigkeit bis zu 16 Dezimalstellen.
Gruß
Andreas
Re: Datenkonvertierung mit großen Zahlen
Hi Hubert,brandelh hat geschrieben:Hi,
was genau muss den dein Job in diesem Falle erledigen ?
eigentlich ist ein ganz triviales Problem. Es sollen zwei Datenbanken mit dem zu erstellenden Interface verbunden werden. Beispiel: In der ersten Datenbuch suche in einer Tabelle nach dem Satz mit der Bedindung "firma = 2". In diesem Satz steht nun die besagte objectid. Mit der objectid gehe ich nun auf eine zweite Tabelle derselben Datenbank und selektiere eine Gruppe von Sätzen. Diese Sätze sollen nun - mit kleineren Manipulationen - in eine Tabelle der zweiten Datenbank geschrieben werden. Leider sind die Manipulation nun doch so komplex, da es sich nicht mit SQL alleine lösen läßt.
Wo kann ich mich den über PowerBasic ein wenig schlau machen oder vielleicht sogar Beispiele finden. Auf der Webseite bzw. im Handbuch habe bei einer ersten schnellen Suche nichts zu Datenbanken und ODBC gefunden. Alternativ habe ich mal bei PureBasic (100 Euro preiswerter) nachgeschaut und auf Anhieb Beispiele für ODBC-Verbindungen gefunden. So auf Anhiebt wüßte ich nicht welches der beiden Basic-Varianten die bessere ist.
Gruß
Andreas
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Hi,
PureBasic zu PowerBasic ist wie Xharbour zu Xbase++
PureBasic ist spottbillig (ich meine 50 Euro für eine lebenslange Lizenz) und hat - laut Handbuch - sehr viele Funktionen.
Incl. ODBC native ... und es kann auch für Linux Software entwickelt werden. Sicher kein schlechtes System.
Allerdings war (und ist) die Syntax deutlich unterschiedlich zu meinem alten DOS PowerBasic.
Daher habe ich mich für PowerBasic für Windows (PBWin) und für die Comandozeile (PBCC) entschieden.
Wenn man beides in der neuesten Version will, braucht man also gut 300 Euro PLUS die Bibliothek SQLTools (kostenpflichtig).
Also ich meine PureBasic Lizenz kaufte, war PureBasic in einigen Bereichen nicht stabil bzw. fertig, das soll sich geändert haben.
PowerBasic ist eine Firma in den USA www.powerbasic.com, die Vorgängerversion (=> Classic) kostet etwa die Hälfte der aktuellen,
beide sind ihr Geld wert - von der Höhe auch kein Vergleich zu Xbase++ oder WinDev
Der Vorteil beider Sprachen sind sehr kleine sehr schnelle Programme und die Unterstützung von allen möglichen Datentypen.
Der Nachteil natürlich eine komplett andere Sprache im Vergleich zu Xbase++, gerade wenn man sich an classen und codeblocks gewöhnt
hat, vermisst man diese sehr schnell bei den Basic Varianten.
Es müsste möglich sein, eine Art von "Zwischenübersetzer" DLL zu generieren, die sich um die Übersetzung z.B. 18 Stellen NUMERISCH in
String mit 18 Byte kümmert den du in deinem Xbase++ Programm nutzt. Da stellt sich aber auch gleich eine andere Frage (besser 2):
1. Wie genau kommst du an die ODBC-Daten ? SQL-Express oder ODBCDBE ?
Wenn du mit SQL-Express nutzt, sieh auf deren Seite nach bzw. frage dort nach,
ob die einen 8 Byte SQL Wert als String übergeben können.
http://www.sqlexpress.com/menu.htm -> SQLValue() CLASS
die Erläuterung scheint mir auf dein Problem zu passen.
2. Pablo hat in OT4XB alle möglichen Datentypen für DLL Zugriffe im Angebot. Hast du das mal durchgesehen ?
http://www.xbwin.com/ot4xbXHlp/ -> eventuell kann dir diese etwas nützen.
auf der Seite ist auch ein Forum für SQL-Express verfügbar.
Hier ist mal ein Beispiel wie ich eine MySQL Datenbank erstelle und eine Tabelle anlege.
Unter Xbase++ sind die vergleichbaren DBF Dateien 600 MB groß, PowerBasic mit SQLTools braucht
bei dem Beispiel weniger als 1/10 der Zeit wie Xbase++ und SQL-Express ...
Wie gesagt, wenn du es schaffst in XBase++ nur einen String zu erhalten ist dein Problem gelöst.
Als hardwarenahe Unterstütztung sind beide Basic Varianten oder Delphi auf jeden Fall empfehlenswert.
Ob du die Zeit hast weiß ich nicht.
Sowohl ODBC als auch ActiveX könnten eine beschleunigte Zwischenstation brauchen,
das Lernen wäre also nicht unnötig.
PureBasic zu PowerBasic ist wie Xharbour zu Xbase++
PureBasic ist spottbillig (ich meine 50 Euro für eine lebenslange Lizenz) und hat - laut Handbuch - sehr viele Funktionen.
Incl. ODBC native ... und es kann auch für Linux Software entwickelt werden. Sicher kein schlechtes System.
Allerdings war (und ist) die Syntax deutlich unterschiedlich zu meinem alten DOS PowerBasic.
Daher habe ich mich für PowerBasic für Windows (PBWin) und für die Comandozeile (PBCC) entschieden.
Wenn man beides in der neuesten Version will, braucht man also gut 300 Euro PLUS die Bibliothek SQLTools (kostenpflichtig).
Also ich meine PureBasic Lizenz kaufte, war PureBasic in einigen Bereichen nicht stabil bzw. fertig, das soll sich geändert haben.
PowerBasic ist eine Firma in den USA www.powerbasic.com, die Vorgängerversion (=> Classic) kostet etwa die Hälfte der aktuellen,
beide sind ihr Geld wert - von der Höhe auch kein Vergleich zu Xbase++ oder WinDev
Der Vorteil beider Sprachen sind sehr kleine sehr schnelle Programme und die Unterstützung von allen möglichen Datentypen.
Der Nachteil natürlich eine komplett andere Sprache im Vergleich zu Xbase++, gerade wenn man sich an classen und codeblocks gewöhnt
hat, vermisst man diese sehr schnell bei den Basic Varianten.
Es müsste möglich sein, eine Art von "Zwischenübersetzer" DLL zu generieren, die sich um die Übersetzung z.B. 18 Stellen NUMERISCH in
String mit 18 Byte kümmert den du in deinem Xbase++ Programm nutzt. Da stellt sich aber auch gleich eine andere Frage (besser 2):
1. Wie genau kommst du an die ODBC-Daten ? SQL-Express oder ODBCDBE ?
Wenn du mit SQL-Express nutzt, sieh auf deren Seite nach bzw. frage dort nach,
ob die einen 8 Byte SQL Wert als String übergeben können.
http://www.sqlexpress.com/menu.htm -> SQLValue() CLASS
die Erläuterung scheint mir auf dein Problem zu passen.
2. Pablo hat in OT4XB alle möglichen Datentypen für DLL Zugriffe im Angebot. Hast du das mal durchgesehen ?
http://www.xbwin.com/ot4xbXHlp/ -> eventuell kann dir diese etwas nützen.
auf der Seite ist auch ein Forum für SQL-Express verfügbar.
Hier ist mal ein Beispiel wie ich eine MySQL Datenbank erstelle und eine Tabelle anlege.
Unter Xbase++ sind die vergleichbaren DBF Dateien 600 MB groß, PowerBasic mit SQLTools braucht
bei dem Beispiel weniger als 1/10 der Zeit wie Xbase++ und SQL-Express ...
Code: Alles auswählen
#DIM ALL
#REGISTER NONE
#COMPILE EXE "\SQLTOOLS\MySQL_FILL.EXE"
#COMPILER PBCC
%FAST = -1 ' prepare / execute trennen
%AnzahlRecords = 3000000
%lMaxDatabaseNumber = 2 ' 2 ist Standard
%lMaxStatementNumber = 2 ' 2 ist Standard
%lMaxColumnNumber = 120 ' 32 ist Standard und Minimum, bis zu 999
%lMaxParameterNumber = 3 ' 3 ist Standard
'Remove the comment mark (') from ONE of these lines:
'$INCLUDE "\SQLTOOLS\SQLT_STD.INC"
$INCLUDE "\SQLTOOLS\SQLT_PRO.INC"
DECLARE FUNCTION MainProgram AS LONG
FUNCTION WINMAIN(BYVAL hInstance AS DWORD, _
BYVAL hPrevInst AS DWORD, _
BYVAL lpszCmdLine AS ASCIIZ PTR, _
BYVAL nCmdShow AS LONG ) AS LONG
IF SQL_Authorize(%MY_SQLT_AUTHCODE) <> %SUCCESS THEN
SQL_MsgBox "OOOOPS - Error in Authcode ?", %MSGBOX_OK
EXIT FUNCTION
END IF
SQL_Initialize %lMaxDatabaseNumber,_
%lMaxStatementNumber,_
%lMaxColumnNumber,_
%lMaxParameterNumber,3,0,0,hInstance
FUNCTION = MainProgram
SQL_Shutdown
END FUNCTION
FUNCTION MainProgram AS LONG
LOCAL cX, sSQLStatement,cParameter AS STRING
LOCAL nResult AS WORD
LOCAL x AS LONG
LOCAL nStart,nStop AS LONG
LOCAL nDauer AS SINGLE
LOCAL azString1 AS ASCIIZ * 11
LOCAL azString2 AS ASCIIZ * 21
LOCAL nInd1,nInd2,nInd3 AS LONG
CLS
LOCATE 1,1
? "Start:",TIME$
? "Recno:"
nStart = TIMER
nResult = SQL_OpenDB("DRIVER=MySQL ODBC 3.51 Driver;SERVER=localhost;UID=ODBC;PWD=odbc;DATABASE=TEST")
' Datenbank öffnen
IF SQL_Okay(nResult) THEN
SQL_ErrorClearAll
ELSE
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
END IF
IF SQL_ErrorPending THEN
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
END IF
' Alte Tabelle löschen
sSQLStatement = "DROP TABLE TEST"
SQL_Stmt %SQL_STMT_IMMEDIATE, sSQLStatement
IF SQL_ErrorPending THEN
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
END IF
' Tabelle neu anlegen
sSQLStatement = "CREATE TABLE TEST ( RECNO INT not null primary key,"+_
"IMP_DAT char(8) default ' ' ,"+_
"LIEFER char(5) default ' ' ,"+_
"AKTENZEI char(20) default ' ' ,"+_
"KAT char(3) default ' ' ,"+_
...
"XXXX char(8) default ' ')"
SQL_Stmt %SQL_STMT_IMMEDIATE, sSQLStatement
IF SQL_ErrorPending THEN
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
END IF
#IF %FAST
? "FAST !!!!"
SQL_Stmt %SQL_STMT_PREPARE, "INSERT INTO TEST (recno,Feld1, Feld2) VALUES (?,?,?)"
SQL_BindParam 1, _ 'bind parameter #1
%SQL_PARAM_INPUT, _ 'this is an input parameter
%BAS_LONG, _ 'BASIC data type
%SQL_INTEGER, _ 'SQL data type
11, _ 'display size of a SQL_INTEGER
0, _ 'digits after the decimal point
VARPTR(x), _ 'pointer to variable to receive data
SIZEOF(x), _ 'size of variable
nInd1 'indicator variable (required)
'Bind the ASCIIZ string
SQL_BindParam 2, _ 'lParameterNumber&, _
%SQL_PARAM_INPUT, _ 'lParamType&, _
%BAS_ASCIIZ, _ 'lBasType&, _
%SQL_CHAR, _ 'lSQLType&, _
10, _ 'lDisplaySize&, _
0, _ 'lDigits&, _
VARPTR(azString1), _ 'lPointerToBuffer&, _
SIZEOF(azString1)-1, _ 'lBufferLen&, _
nInd2 'lIndicator&
'Bind the ASCIIZ string
SQL_BindParam 3, _ 'lParameterNumber&, _
%SQL_PARAM_INPUT, _ 'lParamType&, _
%BAS_ASCIIZ, _ 'lBasType&, _
%SQL_CHAR, _ 'lSQLType&, _
20, _ 'lDisplaySize&, _
0, _ 'lDigits&, _
VARPTR(azString2), _ 'lPointerToBuffer&, _
SIZEOF(azString2)-1, _ 'lBufferLen&, _
nInd3 'lIndicator&
#ELSE
? "SLOW ****"
#ENDIF
FOR x = 1 TO %AnzahlRecords
cX = FORMAT$(x)
IF RIGHT$(cX,2)="00" THEN
LOCATE 2,10
? cX
#IF %FAST
azString1 = "Start"
azString2 = "Autor Hubert Müller"
#ELSE
cParameter = "("+cX+",'Start','Autor Hubert Müller')"
#ENDIF
ELSE
#IF %FAST
azString1 = "IN"
azString2 = "äöü ß ÄÖÜ ^$§&/"
#ELSE
cParameter = "("+cX+",'IN','äöü ß ÄÖÜ ^$§&/')"
#ENDIF
END IF
#IF %FAST
nInd1 = 0
nInd2 = LEN(azString1)
nInd3 = LEN(azString2)
SQL_Stmt %SQL_STMT_EXECUTE,""
#ELSE
SQL_Stmt %SQL_STMT_IMMEDIATE, "INSERT INTO TEST (recno,Feld1,Feld2) VALUES "+cParameter
#ENDIF
IF SQL_ErrorPending THEN
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
END IF
NEXT
nStop = TIMER
nDauer = nStop-nStart
? "End: ",TIME$
? "Recno:",SQL_ResRowCount,"vor dem count()"
IF nDauer < 120 THEN
? "Dauer:",nDauer " Sekunden, das sind " (x-1)/MAX(nDauer,1) " Rec/Sec"
ELSE
? "Dauer:",nDauer/60 " Minuten, das sind " (x-1)/MAX(nDauer,1) " Rec/Sec"
END IF
?
IF SQL_ErrorPending THEN
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
END IF
? "select * from ..."
nStart = TIMER
? "Start:",TIME$
SQL_Stmt %SQL_STMT_IMMEDIATE,"SELECT * FROM TEST"
IF SQL_ErrorPending THEN
DO WHILE SQL_ErrorPending
SQL_MsgBox SQL_ErrorQuickOne, %MSGBOX_OK
LOOP
SQL_CloseDB
EXIT FUNCTION
END IF
? "Recno:",SQL_ResRowCount,"nach SELECT"
? "Anzahl der Spalten:",SQL_ResColCount
? "End: ",TIME$
nStop = TIMER
nDauer = nStop-nStart
IF nDauer < 120 THEN
? "Dauer:",nDauer " Sekunden, das sind " SQL_ResRowCount/MAX(nDauer,1) " Rec/Sec"
ELSE
? "Dauer:",nDauer/60 " Minuten, das sind " SQL_ResRowCount/MAX(nDauer,1) " Rec/Sec"
END IF
nStart = TIMER
SQL_Stmt %SQL_STMT_IMMEDIATE, "SELECT COUNT(*) FROM TEST"
IF SQL_ErrorPending THEN
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
SQL_CloseDB
EXIT FUNCTION
ELSE
SQL_Fetch %NEXT_ROW
nStop = TIMER
nDauer = nStop-nStart
? "SELECT COUNT(*) FROM TEST",SQL_ResColText(%ALL_COLs),nDauer,"Sekunden"
END IF
?
? "Dateiinfos:"
PRINT "SQL_DBInfoStr(DB_DM_VER)" TAB(40) SQL_DBInfoStr(%DB_DM_VER)
PRINT "SQL_DBInfoStr(DB_ODBC_VER)" TAB(40) SQL_DBInfoStr(%DB_ODBC_VER)
PRINT "SQL_DBInfoStr(DB_DRIVER_NAME)" TAB(40) SQL_DBInfoStr(%DB_DRIVER_NAME)
PRINT "SQL_DBInfoStr(DB_DRIVER_VER)" TAB(40) SQL_DBInfoStr(%DB_DRIVER_VER)
PRINT "SQL_DBInfoStr(DB_DRIVER_ODBC_VER)" TAB(40) SQL_DBInfoStr(%DB_DRIVER_ODBC_VER)
PRINT "SQL_DBInfoStr(DB_DBMS_NAME)" TAB(40) SQL_DBInfoStr(%DB_DBMS_NAME)
PRINT "SQL_DBInfoStr(DB_DBMS_VER)" TAB(40) SQL_DBInfoStr(%DB_DBMS_VER)
SQL_CloseDB
SQL_MsgBox "Done.", %MSGBOX_OK
END FUNCTION
'============================================ end of SQL-SKEL.BAS
Als hardwarenahe Unterstütztung sind beide Basic Varianten oder Delphi auf jeden Fall empfehlenswert.
Ob du die Zeit hast weiß ich nicht.
Sowohl ODBC als auch ActiveX könnten eine beschleunigte Zwischenstation brauchen,
das Lernen wäre also nicht unnötig.
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Hi,
oben steht ja, dass du mit "XBase 1.80 mit SQL-Express ausgegraben" arbeitest.
Also nicht verzagen, Version prüfen, eventuell upgraden (da müsste SQL-Express reichen),
und Boris fragen wie du die SQL 64Bit unsigned als 18 Stellen String an Xbase++ übergibst und umgekehrt
Das geht am schellsten.
oben steht ja, dass du mit "XBase 1.80 mit SQL-Express ausgegraben" arbeitest.
Also nicht verzagen, Version prüfen, eventuell upgraden (da müsste SQL-Express reichen),
und Boris fragen wie du die SQL 64Bit unsigned als 18 Stellen String an Xbase++ übergibst und umgekehrt
Das geht am schellsten.
Gruß
Hubert
Hubert
- Herbert
- Der Entwickler von "Deep Thought"
- Beiträge: 1991
- Registriert: Do, 14. Aug 2008 0:22
- Wohnort: Gmunden am Traunsee, Österreich
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Mathematisch besteht doch die Möglichkeit, eine 64-Bit Zahl "aufzuteilen"
Die 64-Bit Zahl muss in einen höheren und einen tieferen Teil aufgeteilt werden.
Den höheren Teil um 4.294.967.296, also 2 hoch 32 multiplizieren und dem unteren Teil hinzuaddieren.
Siehe auch den passenden MSDN-Eintrag http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Die 64-Bit Zahl muss in einen höheren und einen tieferen Teil aufgeteilt werden.
Den höheren Teil um 4.294.967.296, also 2 hoch 32 multiplizieren und dem unteren Teil hinzuaddieren.
Code: Alles auswählen
value = Abs(objLargeInt.HighPart *2^32 + objLargeInt.LowPart)
Grüsse Herbert
Immer in Bewegung...
Immer in Bewegung...
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Hallo Herbert,
das muss aber schon in SQL-Express geschehen, denn wenn dort die Umsetzung auf den Xbase++ Datentyp erfolgt ist, stimmt der Wert schon nicht mehr.
Ich vermute dazu gibt es die SQLValue() Klasse, aber damit habe ich keine Erfahrungen.
das muss aber schon in SQL-Express geschehen, denn wenn dort die Umsetzung auf den Xbase++ Datentyp erfolgt ist, stimmt der Wert schon nicht mehr.
Ich vermute dazu gibt es die SQLValue() Klasse, aber damit habe ich keine Erfahrungen.
Gruß
Hubert
Hubert
- Herbert
- Der Entwickler von "Deep Thought"
- Beiträge: 1991
- Registriert: Do, 14. Aug 2008 0:22
- Wohnort: Gmunden am Traunsee, Österreich
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Datenkonvertierung mit großen Zahlen
Du hast schon recht.
Interessant ist für mich, das die Upper-Hälfte offensichtlich korrekt bleibt. Ich hätte dort den Fehler erwartet. Gibt allerdings Raum, z.B. durch das SQL-System den Lower-Part alleine nochmals zu senden.
Eventuell gibts einen andern Trick mit einlesen via Character, um den Lower Part in numeric32 umzuwandeln.
Bin aber da nicht sicher, ob so was zu machen wäre.
Mir war wichtig, die Idee zu sehen.In der Datenbank beinhaltet das Feld den Wert 186385493536103871. Lasse ich mir den Wert in xBase anzeigen, so sehe ich die Zahl 186385493536103900.
Interessant ist für mich, das die Upper-Hälfte offensichtlich korrekt bleibt. Ich hätte dort den Fehler erwartet. Gibt allerdings Raum, z.B. durch das SQL-System den Lower-Part alleine nochmals zu senden.
Eventuell gibts einen andern Trick mit einlesen via Character, um den Lower Part in numeric32 umzuwandeln.
Bin aber da nicht sicher, ob so was zu machen wäre.
Grüsse Herbert
Immer in Bewegung...
Immer in Bewegung...