ubuntuusers.de

Text unter Tcl-Tk-Sqlite3 abspeichern

Status: Gelöst | Ubuntu-Version: Ubuntu 11.10 (Oneiric Ocelot)
Antworten |

drhawo

Anmeldungsdatum:
6. September 2010

Beiträge: 159

Hallo! Nach zwei Monaten Einarbeitung mit Tcl-Tk-Sqlite (nach Ousterhout wären dafür nur 2 Tage notwendig, ich staune) habe ich nun folgendes Problem beim Abspeichern eines Textes in einer Datenbank. Ich will es mit Skript-Segmenten demonstrieren:

package require sqlite3; set nDb /home/hans/p/db/p_hilfe; sqlite3 db $nDb; eine Testzeile läuft korrekt, beide Werte werden abgespeichert : db eval { INSERT INTO t (befe,synt) VALUES ("Monika","Hans")} }

Folgende Prozedur mit Fehlermeldung wird weiter unten aufgerufen: proc sp_t {} { set bN [.o.eb get];# BefehlsName aus einem Entry-Widget. set bS [.m.l.t get 1.0 end]; BefehlsSynthax aus dem Text-Widget. db eval { INSERT INTO t (befe,synt) VALUES ($bN,$bS)}

Hier Abbruch und Meldung: Applikationsfehler Fehler: invalid command name "db" Details: invalid command name "db" while executing "db eval { INSERT INTO t (befe,synt) VALUES ($bN,$bS)}" ...

Offensichtlich ist innerhalb der Prozedur der beim Aufruf von sqlite3 erzeugte neue Tcl-Befehl nicht sichtbar, da er ja oben funktioniert. Was immer ich auch versuche, ich komme nicht weiter. Nun, aller Anfang ist schwer. Ist für euch wahrscheinlich selbstverständlich, vielleicht hilft mir jemand weiter. Dank im voraus, mfg DrHaWo

Ergänzend noch Skriptsegmente zum Text- Entry-und Button-Widget, funktioniert aber alles: text .m.l.t -wid 120; pack .m.l.t -side left -padx 10; label .o.lb -text "Befehl: ";entry .o.eb -width 100; pack .o.lb .o.eb -side left -padx 3

Hier wird die obige Prozedur aufgerufen *** button .m.r.b6 -text "Speichern" -command sp_t; pack .m.r.b6 -side top -padx {30 3} -pady 3

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi,

hab jetzt nicht viel Zeit, evtl. morgen.

Sieht zunächst nicht falsch aus, bis auf die geschweiften Klammern in deiner proc.

Aber bei dem verwirrenden Format, kann das wohl auch ein copy-paste-Felher sein?

Es ist aber schon so: das Command wird global eingerichtet, es ist in der Prozedur verfügbar.

drhawo

(Themenstarter)

Anmeldungsdatum:
6. September 2010

Beiträge: 159

Danke für deine rasche Antwort. Als Anhang sende ich dir die entscheidenden Teile des Originalcodes, woraus du ersehen kannst, dass die geschweiften Klammer-Paare korrekt gesetzt wurden. Ich würde mich auf eine weitere Nachricht von dir freuen, mfg DrHaWo.

Ubuntu-Forum1 (501 Bytes)
Auszug aus dem Original-Skript
Download Ubuntu-Forum1

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi,

also hier mal ein kleines Testprogrämmchen, um dir das zu veranschaulichen. Mir ist noch aufgefallen, dass du Variablen in den geschweiften Klammern verwendest; in geschweifte Klammern wird aber nix ersetzt, d.h. dein Dollar wird durchgereicht und deine Inhalte werden nicht geschrieben.

Den SQL-Ausdruck habe ich daher als String behandelt (Doppelhochkomma).

Das Programm zeigt 2 Texteingaben ("Name" und darunter "Beruf") und darunter einen OK-Button, der das Speichern in die DB auslöst und anschließend den aktuellen Inhalt der Tabelle als Text auf stdout ausgibt.

#! /bin/bash
##  \
exec wish "$0" "$@"


puts "Hallo, hier spricht dein Testprogramm"

package require sqlite3;

sqlite3  db  ./testdb

catch {db eval { CREATE TABLE t1 (name string, beruf string)} };


# schreibt Inhalt von Variable ::gName und ::gBeruf (d.h. globale Variable)
# in die Tabelle t1, die Name mit Beruf verknuepft.
# @return void
proc writeEntry {}  {
  db eval "insert into t1 VALUES('$::gName', '$::gBeruf') ";

  set lst [db  eval {SELECT * FROM  t1 order by name} ]

  # Tabelle ausgeben
  foreach {name beruf} $lst  {
	puts "name=$name  beruf=$beruf"
  }
}


entry .eName     -textvariable gName
entry .eBeruf    -textvariable gBeruf
button .ok       -text OK -command writeEntry

grid .eName
grid .eBeruf
grid .ok

drhawo

(Themenstarter)

Anmeldungsdatum:
6. September 2010

Beiträge: 159

Hallo! Mein Dankeschön kommt etwas verspätet. da mir kein Internet zur Verfügung stand (Nachbar hatte bei Gartenarbeiten meine Telefonleitung gekappt). Alles funktioniert nach deinem Beispiel tadellos. Zusätzlich habe ich noch gelernt, dass man globale Variable mit $::gVar in einer Prozedur verwenden kann und SQL-Befehle mit "" gruppiert wenn man eine Variablensubstitution möchte. Auch der catch-Befehl zur Vermeidung eines Abbruchs, wenn eine Tabelle schon existiert, war mir nicht bekannt, ist aber sehr nützlich.

Ein Problem hat sich jedoch bei der Tabellenspeicherung eines Textes ergeben. Im insert-Befehl von Sqlite3 werden String-Werte in Anführungszeichen gesetzt (... VALUES ('$::gVar',.. ); Kommen im Text Hochkommas vor, bricht das Programm mit einer Fehlermeldung mit dem Hinweis auf das erste Wort zwischen den Hochkommas ab. Ich möchte zwar damit den Thread nicht in unerlaubter Weise erweitern, wäre dir aber für eine Antwort, wenn du eine Lösung bei der Hand hast, dankbar. MfG DrHaWo

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi, das mit dem Hochkomma ist in diesem Falle ein SQL-Spezifika.

Du kannst das umgehen, wenn du die Hochkommata durch zwei aufeinanderfolgende Hochkommata ersetzt ☺

  
regsub -all {'}  $::gName {''} maskedName;

d.h. anschließend mit 'maskedName' in die DB schreiben, nicht mehr mit 'gName'.

drhawo

(Themenstarter)

Anmeldungsdatum:
6. September 2010

Beiträge: 159

Hallo! Danke, du hast mir weiter geholfen und zusätzlich habe ich noch einiges dazugelernt. MfG DrHaWo

Antworten |