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


von Freddy (Gast)


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

von Clemens L. (c_l)


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.

von Freddy (Gast)


Lesenswert?

Hi,

ja das verstehe ich schon.
Aber wenn ich mir das Beispiel aus:
http://sqlite.1065341.n5.nabble.com/Write-to-a-View-td65447.html
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.

1
create trigger "Person Work update"
2
instead of update
3
on "Person Work"
4
begin
5
        update "Person"
6
        set ID = new.ID, "Name First" = new."Name First", "Name Last" = new."Name Last"
7
        where ID = old.ID
8
        ;
9
-- Company:
10
        insert into "Company" ("Name")
11
        select new."Company"
12
        where new."Company" not in (select Name from "Company")
13
                and new."Company" not null
14
        ;
15
        insert into "Person Company" ("ID", "Company")
16
        select
17
                new.ID
18
        , (select ID from "Company" where Name = new."Company")
19
        where new."Company" not null and old."Company" is null -- ie Company was blank but new value entered
20
        ;
21
        delete from "Person Company"
22
        where ID = old.ID
23
                and new."Company" is null and old."Company" not null -- ie Existing Company value deleted
24
        ;
25
        update "Person Company"
26
        set "Company" = (select ID from "Company" where Name = new."Company")
27
        where ID = new.ID
28
                and new."Company" not null and old."Company" is null -- ie Existing Company value changed
29
        ;
30
-- Job Title:
31
        insert into "Job Title" ("Name")
32
        select new."Job Title"
33
        where new."Job Title" not in (select Name from "Job Title")
34
                and new."Job Title" not null
35
        ;
36
        insert into "Person Job Title" ("ID", "Job Title")
37
        select
38
                new.ID
39
        , (select ID from "Job Title" where Name = new."Job Title")
40
        where new."Job Title" not null and old."Job Title" is null -- ie Job Title was blank but new value entered
41
        ;
42
        delete from "Person Job Title"
43
        where ID = old.ID
44
                and new."Job Title" is null and old."Job Title" not null -- ie Existing Job Title value deleted
45
        ;
46
        update "Person Job Title"
47
        set "Job Title" = (select ID from "Job Title" where Name = new."Job Title")
48
        where ID = new.ID
49
                and new."Job Title" not null and old."Job Title" is null -- ie Existing Job Title value changed
50
        ;
51
-- Email:
52
        update "Person Email"
53
        set "Email" = new."Email"
54
        where "Person" = new.ID and "Purpose" = (select ID from "Purpose" where Name = 'Work')
55
                and new."Email" not null and old."Email" not null -- ie changing an existing email address
56
        ;
57
        delete from "Person Email"
58
        where "Person" = new.ID and "Purpose" = (select ID from "Purpose" where Name = 'Work')
59
                and new."Email" is null and old."Email" not null -- ie deleting an existing email address
60
        ;
61
        insert into "Person Email" ("Person", "Email", "Purpose")
62
        select
63
                new.ID
64
        , new."Email"
65
        , (select ID from "Purpose" where Name = 'Work')
66
        where new."Email" not null and old."Email" is null -- adding a email address that didn't exist
67
        ;
68
end
69
;

von Clemens L. (c_l)


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

von Ted (Gast)


Lesenswert?

Was triggert deine Trigger?
Warum würdest Du überhaupt Views updaten?

Ich verstehe das Problem nicht ganz.

von Freddy (Gast)


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.

von Peter II (Gast)


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)

von Freddy (Gast)


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

von Peter II (Gast)


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.

von Ted (Gast)


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.

von Clemens L. (c_l)


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-view-in-the-database-updatable

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.