SQL Daten aus einer Tabelle lesen, verändern und wieder schreiben

KaeTuuN

Rear Admiral
Registriert
Okt. 2002
Beiträge
5.304
Hallo zusammen,

Ich habe eine Tabelle mit knapp 2500 Einträgen und folgendem Aufbau (vereinfacht):
idtitelautor
10012 - Das Geheimnis der ZeitgruftDarlton, Clark
.........
24522599 - Der letzte TagHerren, Marc A.

Was möchte ich machen?
Bei allen Titeln "Perry Rhodan - " vorne anstellen. Also: "Perry Rhodan - " + titel_alt = titel_neu
Kann ich das ganze direkt in SQL machen, oder muss ich die Datensätze dazu auslesen, mit einem externen Skript bearbeiten und wieder wegschreiben?
Vielen Dank für Eure Hilfe.

Mfg Kae
 
Code:
UPDATE tbl
SET titel = CONCAT('Perry Rhodan - ',titel)
 
Vergiss nicht eventuell noch eine passende Where-Klausel an Yuuris vorschlag zu hängen,
es wäre aber theoretisch auch titel='Perry Rhodan - ' + titel gegangen.

Ansonsten empfehle ich die kostenlose Lektüre (zumindest früher wars kostenlos) SQL in 21 Tage, keine Angst
in der Regel braucht man nichtmal 3 Tage dafür ;)
 
Ist ja nicht so, dass es dazu massig (um nicht zu sagen: "unendlich") Infos im Netz dazu gibt. Das steht in jedem Erstklässler-Anfängertutorial zu SQL :p
 
Sehr komisch bei mir tut es das sowohl in MySql als auch auf dem MSSQL 2008/2012, funktioniert normal auch mit DB2,
müssen je nach DB nur die Datentypen auch stimmen, da nicht jede automatisch auf Strings castet.
Dein Link funktioniert da bei mir weniger als der SQL :D
 
Ich habe leider eine entscheidene Information vergessen.
Das ganze ist leider keine SQL, sondern eine SQLite DB, weswegen CONCAT nicht funktioniert. Eigentlich sollte es mit || funktionieren, aber da bekomme ich eine Fehlermeldung. :/

Mfg Kae
 
Hoppla... da habe ich wohl was vergessen... Fehlermeldung:
Code:
ERROR: no such function: title_sort

Query = UPDATE books SET title = "Perry Rhodan - " WHERE id 
IN (9778)
Ich habe nicht den Hauch einer Ahnung, was damit gemeint sein soll, ich kenne die Funktion "title_sort" nicht.

Mfg Kae
 
Da fehlt mir so ein bisschen die Info, wie du das Statement absetzt. Außerdem sind doppelte Anführungszeichen eher bah. Also generell sollte

UPDATE books set titel = 'Perry Rhodan - ' || titel WHERE id IN (9778)

funzen.
Wenn nicht mach ma ein SELECT * FROM sqlite_master WHERE name = 'books' und paste hier das Ergebnis, damit wir mal den Aufbau der Tabelle sehen.
Ergänzung ()

alxtraxxx schrieb:
Sehr komisch bei mir tut es das sowohl in MySql als auch auf dem MSSQL 2008/2012, funktioniert normal auch mit DB2,
müssen je nach DB nur die Datentypen auch stimmen, da nicht jede automatisch auf Strings castet.
Dein Link funktioniert da bei mir weniger als der SQL :D

Das + ist Syntax für MSSQL, keine Ahnung von DB2, bei MySQL geht _eigentlich_ nur CONCAT, optional kann man || benutzen, dazu muss man aber im Ansimodus ausführen, sonst ist das das logische OR ('a' || 'b' gibt dann 0, a || '1' gibt 1 als Ergebnis, großes Tennis). Interessant wird es bei MySQL dann bei SELECT '2' + '1', da macht der Schlawiner auf einmal einen Typecast und gibt 3 zurück :D

Dass bei MySQL + für Konkatenation funktionieren soll habe ich so noch nie gesehen, vielleicht gibts da aber auch, ähnlich wie bei ||, irgendeinen Kompatibilitätsschalter.
 
Interessant wird es bei MySQL dann bei SELECT '2' + '1', da macht der Schlawiner auf einmal einen Typecast und gibt 3 zurück
Ok bei aktuellen Versionen scheint dies immer der Typecast zu sein denn 'test' + <varcharfeld> ergibt auch 0 ;)

Ist schon ein paar Jahre her aber damals bin ich mir ziemlich sicher dass es auf meinen MySQL-Servern funktionierte, lag aber vielleicht an der genutzten Treiberschicht das es ging, je nachdem welche Software man als Frontend nutzt funktionieren ja manchmal SQLs oder auch nicht X)
 
alxtraxxx schrieb:
Lag aber vielleicht an der genutzten Treiberschicht das es ging, je nachdem welche Software man als Frontend nutzt funktionieren ja manchmal SQLs oder auch nicht X)

Treiberschicht vielleicht nicht unbedingt, vielleicht hattest du da noch so ein Kompatibilitätszeug dahinter, was für verschiedene Datenbanken übersetzt hat? Ich hatte gestern schonmal geguckt, Operator Overloading kann MySQL nicht, sonst hätte ich gesagt in deiner Firma hat vielleicht mal jemand einen fiesen Hack geschrieben um die Abfragen zwischen Oracle, DB2 und MySQL kompatibel zu machen :D
 
Abfrage:
Code:
SELECT * FROM sqlite_master WHERE name = 'books'

Ergebnis:
Code:
type	name	tbl_name	rootpage	sql
table	books	books		4	     CREATE TABLE books ( id      INTEGER PRIMARY KEY AUTOINCREMENT,
		                             title     TEXT NOT NULL DEFAULT 'Unknown' COLLATE NOCASE,
		                             sort      TEXT COLLATE NOCASE,
		                             timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
		                             pubdate   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
		                             series_index REAL NOT NULL DEFAULT 1.0,
		                             author_sort TEXT COLLATE NOCASE,
		                             isbn TEXT DEFAULT "" COLLATE NOCASE,
		                             lccn TEXT DEFAULT "" COLLATE NOCASE,
		                             path TEXT NOT NULL DEFAULT "",
		                             flags INTEGER NOT NULL DEFAULT 1,
		                             uuid TEXT,
		                             has_cover BOOL DEFAULT 0,
		                             last_modified TIMESTAMP NOT NULL DEFAULT "2000-01-01 00:00:00+00:00")

Weitere Informationen:
Das ganze ist eine SQLite 3.x DB, die von Calibre 2.40.0 (aktuelle Version) erstellt wurde.
Zum bearbeiten nutze ich RazorSQL 64-Bit und SQLite Studio 64-Bit.

Vielen dank bis hierher schonmal für die Hilfen!

Mfg Kae
 
Und was sagt


UPDATE books set title = 'Perry Rhodan - ' || title WHERE id IN (9778)

? (also vorrausgesetzt die ID gibts ;)) Ich hab das hier gerade mal auf SQLite3 getestet und es lief eigentlich problemlos...
 
Da kommt der Fehler, den ich bereits in Post #9 geschrieben habe. Die ID gibt es definitiv. Zumindest bekomme ich genau eine Zeile ausgespuckt, wenn ich
Code:
SELECT * FROM 'books' WHERE id IN (9778)
eingebe.

Mfg Kae
 
Es handelt sich um einen benutzerdefinierte Funktion von Calibre: https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.create_function
Hier wird sie an die Datenbank-Verbindung gebunden: https://github.com/kovidgoyal/calib...228d275645/src/calibre/library/sqlite.py#L224
Und hier ist sie implementiert: https://github.com/kovidgoyal/calib.../src/calibre/ebooks/metadata/__init__.py#L130

Jetzt ist nur die Frage, wie man diese Funktion umgeht oder nachbildet damit man RazorSQL oder SQLite Studio verwenden kann.

Edit:
SQL:
select * from sqlite_master where type = 'trigger' and sql like '%title_sort%';
SQL:
CREATE TRIGGER books_insert_trg AFTER INSERT ON books
    BEGIN
        UPDATE books SET sort=title_sort(NEW.title),uuid=uuid4() WHERE id=NEW.id;
    END

CREATE TRIGGER books_update_trg
    AFTER UPDATE ON books
    BEGIN
    UPDATE books SET sort=title_sort(NEW.title)
        WHERE id=NEW.id AND OLD.title <> NEW.title;
    END

Wie mambokurt sagte, Trigger droppen und neu erstellen sollte hinhauen.
 
Zuletzt bearbeitet:
Also wenn r15ch13 das richtig recherchiert hat müsste es entsprechend so gehen:
Code:
DROP TRIGGER books_update_trg;

UPDATE books set title = 'Perry Rhodan - ' || title WHERE id IN (9778,..,..);

CREATE TRIGGER books_update_trg
    AFTER UPDATE ON books
    BEGIN
    UPDATE books SET sort=title_sort(NEW.title)
        WHERE id=NEW.id AND OLD.title <> NEW.title;
    END

Ich hatte jetzt verpasst ob du alle Einträge updaten willst oder nur manche, wenns alle sind kannst du das WHERE id IN (9778,..,..) natürlich weglassen. So, High Five an r15ch13 und viel Erfolg damit :D
 
Zurück
Oben