Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sql Datenbank und binäre Daten

14 views
Skip to first unread message

Jan Schmidt

unread,
Jul 5, 2017, 4:24:01 PM7/5/17
to
Hi,

ich möchte mit QtSQL (vorzugsweise sqlite / mysql) eine größere Menge
float-Daten speichern, die später weiterverarbeitet werden sollen.

Mich stört die doppelte Wandlung von float in ASCII - aus Rechenzeit-
und vor allem Genauigkeitsgründen.

Für das speichern mit insert funktioniert das mit preallocated statements:

query.prepare
query.bindValue
query.exec()

Wie stelle ich das bei der Abfrage mit select an?

Ich habe das Beispiel von hier

https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html

versucht.

void test_preallocated_statement (QSqlDatabase &db)
{
QSqlQuery query;
if (!query.exec("SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2))
AS hypotenuse';PREPARE stmt2 FROM @s;SET @a = 6; SET @b = 9;"))
{
LOG_FAILED_QUERY(query);
//return
}
if (!query.exec("EXECUTE stmt2 USING @a, @b;"))
{
LOG_FAILED_QUERY(query);
//return
}

QSqlRecord record = query.record();
qDebug() << "Number of columns: " << record.count();
while (query.next())
{
QString line = query.value(0).toString();
qDebug() << "result from mysql: " << line;
}
if (!query.exec("DEALLOCATE PREPARE stmt2;"))
{
LOG_FAILED_QUERY(query);
}

}

und mit dem wireshark kontrolliert, was übertragen wird:

Frame 1552: 145 bytes on wire (1160 bits), 145 bytes captured
(1160 bits) on interface 0
Transmission Control Protocol, Src Port: mysql (3306), Dst Port:
59928 (59928), Seq: 157, Ack: 240, Len: 79
MySQL Protocol
Packet Length: 1
Packet Number: 1
Number of fields: 1
MySQL Protocol
Packet Length: 32
Packet Number: 2
Catalog: def
Database:
Table:
Original table:
Name: hypotenuse
Original name:
Charset number: binary COLLATE binary (63)
Length: 23
Type: FIELD_TYPE_DOUBLE (5)
Flags: 0x0080
Decimals: 31
MySQL Protocol
Packet Length: 5
Packet Number: 3
EOF marker: 254
Warnings: 0
Server Status: 0x0002
MySQL Protocol
Packet Length: 16
Packet Number: 4
text: 10.816653826392
MySQL Protocol
Packet Length: 5
Packet Number: 5
EOF marker: 254
Warnings: 0
Server Status: 0x0002

Das Ergebnis sind nicht 4 (8) byte sondern 16 - ASCII codiert.

Hat jemand eine Idee?
Würde sich sqlite anders verhalten?

Gruß,
Jan

Thomas Orgelmacher

unread,
Jul 6, 2017, 4:50:02 PM7/6/17
to
Moin!

Am 05.07.2017 um 22:24 schrieb Jan Schmidt:
>
> ich möchte mit QtSQL (vorzugsweise sqlite / mysql) eine größere Menge
> float-Daten speichern, die später weiterverarbeitet werden sollen.

Sqlite3 und MySql liegen schon beliebig weit auseinander...

> Mich stört die doppelte Wandlung von float in ASCII - aus Rechenzeit-
> und vor allem Genauigkeitsgründen.

Sorry, ich kenne QtSQL nicht, aber Sqlite3 kann Doubles definitiv nativ
speichern und ich vermute (mangels Erfahrung), MySql kann das ebenfalls.

Obwohl ich gewöhnlich keine Manuals für andere lese: in den QtSQL Docs steht
da ganz deutlich bei Float/Double: "By default mapping to QString" für Sqlite3
als auch für MySql.

Was da jetzt der möglich Override ist: keine Ahnung.


Thomas

--
I have seen things you lusers would not believe. I've seen Sun
monitors on fire off the side of the multimedia lab. I've seen
NTU lights glitter in the dark near the Mail Gate. All these
things will be lost in time, like the root partition last week.

Jan Schmidt

unread,
Jul 7, 2017, 3:00:38 PM7/7/17
to
On 06.07.2017 22:46, Thomas Orgelmacher wrote:
> Moin!
>
> Am 05.07.2017 um 22:24 schrieb Jan Schmidt:
>>
>> ich möchte mit QtSQL (vorzugsweise sqlite / mysql) eine größere Menge
>> float-Daten speichern, die später weiterverarbeitet werden sollen.
>
> Sqlite3 und MySql liegen schon beliebig weit auseinander...
>
>> Mich stört die doppelte Wandlung von float in ASCII - aus Rechenzeit-
>> und vor allem Genauigkeitsgründen.
>
> Sorry, ich kenne QtSQL nicht, aber Sqlite3 kann Doubles definitiv nativ
> speichern und ich vermute (mangels Erfahrung), MySql kann das ebenfalls.
>
> Obwohl ich gewöhnlich keine Manuals für andere lese: in den QtSQL Docs
> steht
> da ganz deutlich bei Float/Double: "By default mapping to QString" für
> Sqlite3
> als auch für MySql.

danke für die Mühe...

Andere hatten das Problem auch. Ich habe im devel-Forum von Mysql als
Erklärung gefunden, dass bestimmte Arten von selects nicht
funktionieren, wenn die nicht in Text konvertiert werden.

Postgres überträgt gar nichts binär.

Sqlite ist vom sql eingeschränkt, so dass diese Art Abfragen vermutlich
gar nicht funktionieren. Mit meinen Versuchen konnte ich floats korrekt
schreiben und lesen. QVariant hat hier als Typ qlonglong und nicht
String zurückgegeben. Allerdings ist das Debugging hier nicht so einfach
wie mit wireshark. Sicher weiß ich das noch nicht.

(sqlite geistert bei den Auftraggebern herum, ich wollte eine
Alternative suchen. QtSQL ist da eine schöne Abstraktionsschicht.)

jan

0 new messages