Seite 1 von 1
UNIX_TIMESTAMP() mit QSqlTableModel
Verfasst: 28. März 2008 18:08
von pfusterschmied
Hallo,
Ich möchte folgenden SQL Befehl ausführen:
Code: Alles auswählen
UPDATE `my_DB`.`my_Table` SET `tstamp` = UNIX_TIMESTAMP() WHERE `my_Table`.`uid` =682 LIMIT 1 ;
Hintergrund:
Ich möchte jede Änderung an den MySQL Datensätzen mit einer Timestamp versehen.
Da ich mit meiner QSqlTableModel arbeite habe ich probleme die MySQL Anweisung umzusetzten. Ist es möglich diesen MySQL Befehl mit setData() des QSqlTableModel auszuführen?
Folgendes funktioniert nicht:
Code: Alles auswählen
OnlineModel->setData(OnlineModel->index(row,2),"UNIX_TIMESTAMP()");
Da ja nur jener timestamp des veränderten Datensatzes aktualisiert werden darf und ich in einer QTableView arbeite habe ich mit einem normalen QSqlQuery auch probleme.
Wäre für jeden kleinen Tipp dankbar, da ich schon seit Stunden auf dem Schlauch stehe.
Verfasst: 28. März 2008 19:19
von pfusterschmied
Mit QSqlQuery funktioniert es einwandfrei!
Nun bräuchte ich nur noch irgenwie den richtigen Datensatz ansprechen.
Möglicherweise über QIndex und die uid ???? K.A.
Code: Alles auswählen
QSqlQuery insertTime(QSqlDatabase::database ("online"));
insertTime.prepare("UPDATE `my_DB`.`my_Table` SET `tstamp` = UNIX_TIMESTAMP() WHERE `my_Table`.`uid` =682 LIMIT 1 ; ");
insertTime.exec();
Teillösung gefunden
Verfasst: 29. März 2008 10:46
von pfusterschmied
So ich hab jetzt zumindest einen kleinen Fortschritt erreicht. Mit folgendem Code wird bei jedem Klick auf die TableView automatisch in die TS Spalte was geschrieben:
Code: Alles auswählen
connect (tableViewOnline, SIGNAL(clicked(const QModelIndex) ),this,SLOT(changeTime(const QModelIndex) ));
void dbselect::changeTime(const QModelIndex index)
{
QSqlRecord record = MySqlTableModel->record(index.row());
qDebug() << record.value(2);
record.setValue (2,"UNIX_TIMESTAMP()" ); //Liefert Null ???
MySqlTableModel->setRecord (index.row(),record );
// Änderungen übernehmen
submit();
}
Nun bleiben dennoch zwei Probleme bestehen:
Ist es möglich nur ein Signal zu senden, wenn Daten in der TableView geändert werden?
Wie könnte ich einen Workaround bewerkstelligen, wenn UNIX_TIMESTAMP() anscheinend nicht als SQL Befehl gesetzt wird?
Bitte um kleinen Beistand!
Verfasst: 29. März 2008 16:35
von upsala
Entweder du verwendest eine Datenbank die das von sich aus kann (Postgres z.B.) oder du überlädst updateRowInTable
Verfasst: 30. März 2008 23:32
von pfusterschmied
Danke für den Tipp:
.. oder du überlädst updateRowInTable
Upsala, was würde ich nur ohne dich machen. Ich glaube du hast 80% aller meiner Posts beantwortet. Woher nimmst du bloß die Zeit dafür?
Die Methode der Klasse QSqlTableModel ist wie in der Doku steht virtual protected:
Code: Alles auswählen
bool QSqlTableModel::updateRowInTable ( int row, const QSqlRecord & values ) [virtual protected]
Ich trau mich gar nicht zu fragen aber ...
Als Neuling fehlen mir noch die Basics wie ich nun eine geschütze Methode innerhalb einer Klasse benutzen kann.
Ich vermute mal ich muss mir ne Klasse basteln die von der QSqlTableModel erbt (Polymorphismus) oder?
Ein kurzes Bsp. wäre nett.
Danke
Verfasst: 31. März 2008 09:11
von upsala
Woher nimmst du bloß die Zeit dafür?
Ich frag mich eher, was andere Leute in dieser Zeit machen...
Ich vermute mal ich muss mir ne Klasse basteln die von der QSqlTableModel erbt (Polymorphismus) oder?
Genau
Verfasst: 31. März 2008 11:52
von abelmi
Ich arbeite gerade an einem ähnlichen Problem.
Wir haben die Sache mit den Timestamps über Trigger in der Datenbank (Oracle) gelöst. Dadurch ist sichergestellt, dass die Datensätze auch einen Timestamp erhalten, wenn sie nicht vom Programm aus in die Datenbank geschrieben werden. Dies ist z.B. der Fall beim Einspielen von Testdaten über Füllskripte.
Verfasst: 31. März 2008 12:16
von upsala
Trigger sind bei MySQL erst ab Version 5.1 möglich.
Verfasst: 31. März 2008 13:54
von pfusterschmied
Ich arbeite mit MySQL 5.0....
Bis jetzt habe folgende Fortschitte gemacht:
Ich habe die bereits beschriebene Methode abgeändert. Bei jeden Click in die QTableView wird der entsprechenden TimeStamp des Index geändert:
Code: Alles auswählen
void epconfigurator::changeTime(const QModelIndex index)
{
QSqlRecord record = OnlineModel->record(index.row());
record.setValue (2,"UNIX_TIMESTAMP()" ); // Option 1
//record.setValue (2,"666" ); // Option 2
OnlineModel->setRecord (index.row(),record );
}
Natürlich ist dies nicht im Sinne des Erfinders.
Der Eintrag in die DB erfolgt zwar, jedoch wird die TimeStamp Spalte auf 0 gesetzt.
Wie könnte ich einen Workaround bewerkstelligen, wenn UNIX_TIMESTAMP() anscheinend nicht als SQL Befehl gesetzt wird?
Ich dreh mich seit 2 Tagen im total im Kreis.
Habe mittlerweile ein totales Verständnisproblem:
Wie funktioniert die Abarbeitung bei SQLModel?
QTabelview -> dataChanged -> QSqlTableModel->updateRowInTable() ????
Welches Signal wird gesendet, wenn der Content der QTableView bzw. QSqlTableModel geändert wird?
Weiters habe ich auch versucht auf die updateRowInTable Methode zuzugreifen, .....
leider scheiter ich da noch an den Basics. Muss wohl noch eine Menge C++ lernen.
Code: Alles auswählen
class MyQSqlTableModel : public QSqlTableModel
{
public:
MyQSqlTableModel();
~MyQSqlTableModel();
private slots:
void updateRowInTable ( int row, const QSqlRecord & values );
};
Fehler:
/epconfigurator.h:45: error: conflicting return type specified for 'virtual void MyQSqlTableModel::updateRowInTable(int, const QSqlRecord&)'
/usr/include/qt4/QtSql/qsqltablemodel.h:126: error: overriding 'virtual bool QSqlTableModel::updateRowInTable(int, const QSqlRecord&)'
Fehlermeldung ist mir klar, nur wie ich meine Klassen definieren muss nicht!
Verfasst: 31. März 2008 14:07
von franzf
Bei meinen Projekten mit SQLite hab ich dem QSqlQuery immer ein QDateTime-Objekt übergeben

n der SQL-Tabelle ein "date_time"). Funktioniert problemlos. Da das QSqlTableModel wohl für die updates auch QSqlQuery verwendet, warum versuchst du nicht einfach dem index ein QDateTime::currentDateTime() unterzuschieben? Sollte doch eigentlich klappen...
Verfasst: 31. März 2008 14:35
von pfusterschmied
Klasse Idee, habe ich gerade ausprobiert,
das klappt ja 1A.
Besten Dank, aber:
Ich arbeite an einem Client Programm, welches mir Daten aus einem Online-Anmeldesystem holt (Typo3). Diese Daten sind alle mit einem Unix TimeStamp versehen.
Wenn es dafür eine Lösung gibt währe ich sehr dankbar.
Verfasst: 31. März 2008 14:40
von franzf
Versteh die Frage nicht ganz

Du hast in deiner Tabelle eine Spalte mit dem Type "date_time". Qt konvertiert automatisch (falls notwendig) von QDateTime nach date_time und zurück.
Was du jetzt mit deinem Anmeldesystem machen willst ist mir schleierhaft

Wenn du einen Zugang zur Datenbank hast, kannst du doch die Verbindung direkt mit QSqlDatabase verwenden. Oder was genau willst du da jetzt machen?
Verfasst: 31. März 2008 14:51
von pfusterschmied
Ich habe in der Mysql Datenbank eine Spalte tstamp [ int(10)], welche vom Content Management System (Typo3) automatisch mit einer UNIX_TIMESTAMP() versehen wird.
Spricht der Datensatz in dieser Spalte hat folgendes Format : 1159894375
Nun habe ich eine neue Spalte epdate [datetime] einfach hinzugefügt und deinen Ratschlag befolgt, welche einwandfrei und gut funktioniert.
Wenn nun über das Content Management System ein Eintrag verändert wird ändert sich die tstamp Spalte wenn in meinem Client Programm ein Eintrag verändert wird ändert sich die epdate Spalte.
Da ich nun im Programm überprüfen muss ob der geänderte Datensatz auch aktueller ist als in der DB habe ich nun ein Problem....
Ich hoffe es ist in irgend einer Form verständlich.
Kurz:
Typo3 : UNIX_TIMESTAMP()
QT : ???
Verfasst: 31. März 2008 14:57
von franzf
Du darfst ruhig mal in der Doku blättern, so viele Funktionen bietet QDateTime nicht.
Deine UNIX_TIMESTAMP() zeigt die Anzahl der Sekunden seit "1970-01-01T00:00:00" an. In der Qt-Doku findest du diese Angabe auch.
Code: Alles auswählen
uint unix_timestamp = QDateTime::currentDateTime().toTime_t();
Für den aktuellen Zeitpunkt.
Verfasst: 31. März 2008 15:13
von pfusterschmied
Danke,
wer lesen kann ist natürlich klar im Vorteil.
Jetzt läuft fast alles so wie ich es brauche, muss jetzt "nur" noch einSignal finden dass meine Funktion nur dann aufruft, wenn Daten in der QTableView geändert wurden.
Brauche ich updateRowInTable zwingend dafür oder könnte man das anders auch lösen ?