mikrocontroller.net

Forum: PC-Programmierung SQLite im einen Programm - Grundsatzfragen zu Triggern


Autor: Freddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wer hat Erfahrungen mit SQL Datenbanken und kann mir bezüglich Sqlite 
helfen?
Ich habe eine Datenbank in SQLite erstellt und mir aus mehreren Tabellen 
mehrere Views gebaut.
Leider kann ich keine Views direkt ändern.
Eine Möglichkeit wäre es mit Triggern zu arbeiten. Das klappt für das 
Anfügen auch schon sehr gut. Für das Update blicke ich da noch nicht 
ganz durch. So richtig kompliziert sind meine Tabellen nicht, aber 
teilweise haben sie Fremdschlüssel drin.

Grundsätzlich stellt sich mir die Frage, sollte man in der Datenbank mit 
Triggern arbeiten oder doch das ganze lieber in das eigentliche Programm 
verlagern?
Wenn ich jetzt schon bei Triggern Probleme habe dort durchzusteigen, was 
wird dann erst bei größeren Tabellen passieren?

Wer hat Erfahrung mit Datenbanken und kann mir Tips geben?

Gruß,
Freddy

Autor: Clemens L. (c_l)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freddy schrieb:
> sollte man in der Datenbank mit Triggern arbeiten oder doch das ganze
> lieber in das eigentliche Programm verlagern?

Die UPDATEs musst du so oder so mit SQL-Befehlen machen, die kannst du 
dann auch in Trigger packen.

Mit Triggern kannst du verhindern, dass andere Programme inkonsistente 
Daten erzeugen.

Autor: Freddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ja das verstehe ich schon.
Aber wenn ich mir das Beispiel aus:
http://sqlite.1065341.n5.nabble.com/Write-to-a-Vie...
ansehe frage ich mich ob man das noch in 2 Jahren richtig warten kann 
(es sei denn man arbeitet jeden Tag mit Datenbanken). Und auch das 
Beispiel dort ist nicht sehr komplex.

create trigger "Person Work update"
instead of update
on "Person Work"
begin
        update "Person"
        set ID = new.ID, "Name First" = new."Name First", "Name Last" = new."Name Last"
        where ID = old.ID
        ;
-- Company:
        insert into "Company" ("Name")
        select new."Company"
        where new."Company" not in (select Name from "Company")
                and new."Company" not null
        ;
        insert into "Person Company" ("ID", "Company")
        select
                new.ID
        , (select ID from "Company" where Name = new."Company")
        where new."Company" not null and old."Company" is null -- ie Company was blank but new value entered
        ;
        delete from "Person Company"
        where ID = old.ID
                and new."Company" is null and old."Company" not null -- ie Existing Company value deleted
        ;
        update "Person Company"
        set "Company" = (select ID from "Company" where Name = new."Company")
        where ID = new.ID
                and new."Company" not null and old."Company" is null -- ie Existing Company value changed
        ;
-- Job Title:
        insert into "Job Title" ("Name")
        select new."Job Title"
        where new."Job Title" not in (select Name from "Job Title")
                and new."Job Title" not null
        ;
        insert into "Person Job Title" ("ID", "Job Title")
        select
                new.ID
        , (select ID from "Job Title" where Name = new."Job Title")
        where new."Job Title" not null and old."Job Title" is null -- ie Job Title was blank but new value entered
        ;
        delete from "Person Job Title"
        where ID = old.ID
                and new."Job Title" is null and old."Job Title" not null -- ie Existing Job Title value deleted
        ;
        update "Person Job Title"
        set "Job Title" = (select ID from "Job Title" where Name = new."Job Title")
        where ID = new.ID
                and new."Job Title" not null and old."Job Title" is null -- ie Existing Job Title value changed
        ;
-- Email:
        update "Person Email"
        set "Email" = new."Email"
        where "Person" = new.ID and "Purpose" = (select ID from "Purpose" where Name = 'Work')
                and new."Email" not null and old."Email" not null -- ie changing an existing email address
        ;
        delete from "Person Email"
        where "Person" = new.ID and "Purpose" = (select ID from "Purpose" where Name = 'Work')
                and new."Email" is null and old."Email" not null -- ie deleting an existing email address
        ;
        insert into "Person Email" ("Person", "Email", "Purpose")
        select
                new.ID
        , new."Email"
        , (select ID from "Purpose" where Name = 'Work')
        where new."Email" not null and old."Email" is null -- adding a email address that didn't exist
        ;
end
; 

Autor: Clemens L. (c_l)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Befehle sind notwending, um alle möglichen Änderungen in sechs 
Tabellen abzudecken.

In deinem Programm würdest du insgesamt genau so viele Befehle brauchen 
(aber nicht alle auf einmal).

Autor: Ted (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was triggert deine Trigger?
Warum würdest Du überhaupt Views updaten?

Ich verstehe das Problem nicht ganz.

Autor: Freddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem bei SQLite ist, dass Views Read-Only sind.
Natürlich kann ich ohne Views arbeiten, aber ich hatte es als 
komfortabel empfunden lieber in Views mein INNER JOIN... etc. zu machen 
als später in der Datenbankanbindung.

Gibt es hier jemanden, dessen täglich Brot Datenbanken sind?
Ich bin gespannt, was die empfohlene Vorgehensweise ist.

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freddy schrieb:
> Gibt es hier jemanden, dessen täglich Brot Datenbanken sind?

ja.

> Ich bin gespannt, was die empfohlene Vorgehensweise ist.
nicht sqllite verwenden.

Bei uns werden die Update durch Prozeduren gemacht, aber das gibt es 
scheinbar in sqlite nicht.

View zu updaten, geht zwar aber schön ist das nicht. Spätestens wenn es 
1:N Beziehungen geht es eh nicht mehr.

Bei sqllite würde ich jedes Update einzeln machen (wenn möglich in einer 
Transaktion)

Autor: Freddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter II

was wäre eine Alternative zu Sqlite?
Da es sich nur um kleine Datensätze handelt und das spätere Programm 
möglichst portabel sein sollte verbietet sich a) serverbasierte 
Datenbank und b) irgendwas mit ODBC oder wofür extra Treiber installiert 
werden müssen.

Wäre XML eine Alternative, oder JSON?
Hat nicht alles Vor- und Nachteile?

Viele Grüße

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freddy schrieb:
> was wäre eine Alternative zu Sqlite?

SQLlite geht doch nur nicht, weil du die Views update willst. Eventuell 
sollte du deine Arbeitsweise anpassen.

> Da es sich nur um kleine Datensätze handelt und das spätere Programm
> möglichst portabel sein sollte verbietet sich a) serverbasierte
> Datenbank und b) irgendwas mit ODBC oder wofür extra Treiber installiert
> werden müssen.

das sagt wenig aus. Es gibt genug Datendatenbanken die auch ohne 
Installation laufen. Was heist Portabel Linux - Windows?

firebird gibt es z.b noch.

Wir verwenden SQL-Server von MS. Da gibt es auch eine Embedded Version 
die man mit der Anwendung ausliefert. Aber damit habe ich keine 
Erfahrung. Wir verwenden es nur im Zusammenhang mit einem extra Server.

Autor: Ted (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Read Only Views sind doch in Ordnung. Dass Du sie verwendest ist 
sogar sehr gut, da der "execution plan" wiederverwendet werden kann. Ist 
es ein Problem einfach die Tabellenspalten zu updaten?
Ich gehe mal davon aus Deine Datenstrukturen sind einigermassen 
normalisiert.
https://de.wikipedia.org/wiki/Normalisierung_(Datenbank)
Ich nehme an, Du löst im View Attribute über die Ids der Fremdschlüssel 
auf und wenn man nun updaten will, änderst Du üblicherweise nur den 
Fremdschlüssel um auf einen anderen Eintrag in der Fremdtabelle zu 
verweisen. Eine Änderung der Fremdtabelle an sich, sollte aber hier 
getrennt betrachtet werden und nicht im selben updatestatement.
Das sind natürlich keine Gesetze und kann/soll immer den Umständen 
angepasst werden. Anfangs fährt man sicherlich nicht schlecht damit, da 
man schnell merkt, ob man sich zu viel Arbeit macht.

Autor: Clemens L. (c_l)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freddy schrieb:
> Ich bin gespannt, was die empfohlene Vorgehensweise ist.

INSTEAD-OF-Trigger, oder die Tabellen direkt ändern.

In der Praxis werden updatable Views kaum verwendet, weil sie nicht sehr 
portabel sind.
https://stackoverflow.com/questions/3777918/is-a-v...

> was wäre eine Alternative zu Sqlite?

Es gibt andere SQL-Datenbanken, die nicht in einem separaten Prozess 
laufen (z.B. H2), aber auch dort sind Views read-only.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.