Datenkonvertierung mit großen Zahlen

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
ath
Rookie
Rookie
Beiträge: 6
Registriert: Do, 14. Okt 2010 19:20

Datenkonvertierung mit großen Zahlen

Beitrag von ath »

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
Benutzeravatar
brandelh
Foren-Moderator
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

Beitrag von brandelh »

Hallo,

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
und erhalte dieses Ergebnis:

Code: Alles auswählen

 123456789012345700
 123456789012345700
 123456789012345700
123456789012345700
123456789012345700
123456789012345700
nWert == nZ ? J N
Press any key to continue...
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:
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.
somit akzeptiert die Variable zwar den Wertebereich, aber mehr als 16 Vorkommastellen können nicht wirklich verarbeitet 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
Benutzeravatar
brandelh
Foren-Moderator
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

Beitrag von brandelh »

Mein Tipp, auf 16 Stellen umstellen, soviele Objekte kann es gar nicht geben, dass man mehr als 16 Stellen benötigt - oder Sprache wechseln ;-)

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...
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

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  
Ergebnis:

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
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 ;-)

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
Ob allerdings die ODBC Datenbank-Schnittstelle diese großen Zahlen auch verarbeiten kann ?
Gruß
Hubert
ath
Rookie
Rookie
Beiträge: 6
Registriert: Do, 14. Okt 2010 19:20

Re: Datenkonvertierung mit großen Zahlen

Beitrag von ath »

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
ath
Rookie
Rookie
Beiträge: 6
Registriert: Do, 14. Okt 2010 19:20

Re: Datenkonvertierung mit großen Zahlen

Beitrag von ath »

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
Benutzeravatar
brandelh
Foren-Moderator
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

Beitrag von brandelh »

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.
Gruß
Hubert
ramses
Der Entwickler von "Deep Thought"
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

Beitrag von ramses »

Hi,

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
Benutzeravatar
AUGE_OHR
Marvin
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

Beitrag von AUGE_OHR »

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.
wo steht das im Handbuch ?
DATA Component

Specifications for DBF files
...
Numeric values Fields contain max. 19 bytes, including
decimal point and negative signed prefix
das ist die DBF Spezifkation !

mit solch grossen Zahlen habe ich noch nicht gearbeitet, wenn dann mit BIN2U / U2BIN.
gruss by OHR
Jimmy
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
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

Beitrag von Koverhage »

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 ?
Gruß
Klaus
ath
Rookie
Rookie
Beiträge: 6
Registriert: Do, 14. Okt 2010 19:20

Re: Datenkonvertierung mit großen Zahlen

Beitrag von ath »

ramses hat geschrieben:kannst du den Wert zum speichern nicht in 2 Variablen aufteilen und dann in 2 Datenfelder speichern? (Hi / Low Wert)
Hallo Carlo,

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
ath
Rookie
Rookie
Beiträge: 6
Registriert: Do, 14. Okt 2010 19:20

Re: Datenkonvertierung mit großen Zahlen

Beitrag von ath »

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.
wo steht das im Handbuch ?

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
ath
Rookie
Rookie
Beiträge: 6
Registriert: Do, 14. Okt 2010 19:20

Re: Datenkonvertierung mit großen Zahlen

Beitrag von ath »

brandelh hat geschrieben:Hi,

was genau muss den dein Job in diesem Falle erledigen ?
Hi Hubert,

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
Benutzeravatar
brandelh
Foren-Moderator
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

Beitrag von brandelh »

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 ...

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
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.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
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

Beitrag von brandelh »

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.
Gruß
Hubert
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
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

Beitrag von Herbert »

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.

Code: Alles auswählen

value = Abs(objLargeInt.HighPart *2^32 + objLargeInt.LowPart)
Siehe auch den passenden MSDN-Eintrag http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
brandelh
Foren-Moderator
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

Beitrag von brandelh »

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.
Gruß
Hubert
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
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

Beitrag von Herbert »

Du hast schon recht.
In der Datenbank beinhaltet das Feld den Wert 186385493536103871. Lasse ich mir den Wert in xBase anzeigen, so sehe ich die Zahl 186385493536103900.
Mir war wichtig, die Idee zu sehen.
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...
Antworten