PostgreSQL-Datensatz und Sonderzeichen ...

Anfängerfragen zum Programmieren mit PureBasic.
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von hschmidt »

Hallo Purebasic-Gemeinde,

ich möchte eine Spalte einer PostgreSQL-Tabelle mit Dateinamen füllen, z.B. "C:\Dokumente und Einstellungen\Benutzer1\Verzeichnis\test.bmp".
Jedoch wird der Windows-Dateiname ohne Backslashs eingetragen, dh. "C:Dokumente und EinstellungenBenutzer1Verzeichnistest.bmp". Bei Dateinamen mit Sonderzeichen ("C:\Verzeichnis\Horst's verÜCKter ~# Dateiname.bmp") wird leider gar nichts in die Tabelle geschrieben.

Den "\" könnte ich ja mit ReplaceString einfach verdoppeln, dann klappt es. Für alle Sonderzeichen ist dieser Weg jedoch sicher unsinnig.
Wie löst Ihr das? Kann jemand helfen? (mit SQLite funktioniert es ohne Probleme)

Vielen Dank für jede Idee,
Horst

(WinXP, Purebasic 4.51 -> PostgreSQL 8.3.1 Linux)
Benutzeravatar
shadow
Beiträge: 189
Registriert: 23.03.2005 17:52
Wohnort: Lübeck

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von shadow »

Hallo,

kenne mich mit PostgreSQL nicht so aus. Aber versuche mal deinen String als UTF-8 abzuspeichern. Das sollte das Datenbanksystem auf alle Fälle verstehen können.
ThinkPad T61 (in Gedenken) | PureBasic 4.61 B1 (32) | Windows 7 (32SP1) | ArchLinux (32) | Syllable (32)
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von hschmidt »

shadow hat geschrieben:... Aber versuche mal deinen String als UTF-8 abzuspeichern. Das sollte das Datenbanksystem auf alle Fälle verstehen können.
Hallo shadow,
danke für Deine Antwort.
Ich compiliere im Unicode-Modus - somit sollte UTF8 funktionieren. Die Datenbank ist auch UTF8.
Den Dateinamen hole ich per OpenFileRequester, füge diesen direkt in einen String mit der SQL-Insert-Anweisung und führe dann DatabaseUpdate aus. Und zwischendurch fehlt mir was ... (sowas wie htmlentities() unter PHP).
Wie kann ich diesen String/Datennamen "DB-tauglich" machen?
Danke und Gruß,
Horst
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von ts-soft »

Hast Du den String auch in Apostrophs eingeschlossen?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von AND51 »

Warum nur einzelne Sonderzeichen codieren? Dann codiere doch gleich alles. So musst du nicht selber darauf achten, welche Zeichen du codieren und anschließend decodieren musst.

Es gibt 3 Möglichkeiten, einen String bequem zu codieren.

1. Base64Encoder() — Ist die eleganteste Methode. MySQL hat sogar eingebaute Funktionen, einen String Baas64-zu-codieren; das muss es doch bei PostgreSQL doch auch geben... Andernfalls nimmst du einfach die Funktion von PB.

2. URLEncoder() — Eine Funktion von PB, um Sonderzeichen in einer URL zu codieren. Kannst du ja hierfür "missbrauchen".

3. Per Schleife den String durchgehen und jedes Sonderzeichen manuell mit einem Platzhalter ersetzen.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von hschmidt »

Danke für Eure Unterstützung!

@ Morty: Ich glaube, die UTF8-Geschichte kann als Ursache ausgeschlossen werden. Das Programm und die DB habe ich testweise auch auf ASCII umgestellt mit selben Problem.

@ ts-soft: Ja, die Strings werden sauber übergeben. Ohne Sonderzeichen funktioniert es.

@AND51: An BASE64 habe ich aus Verzweiflung auch schon gedacht. Deine Idee mit URLEncode ist Klasse, jedoch werden die Anführungszeichen nicht encoded - Windows lässt jedoch welche in Dateinamen zu - SEHR SCHADE, mit dieser Krücke hätte ich leben können.

Vielleicht muss ich im String doch alle Sonderzeichen durchgehen ...
Doch was kann die Ursache sein? In SQLite funktioniert es ja.
Gruß,
Horst
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von HeX0R »

Beim HistoryViewer muss ich der Postgre-Datenbank auch Dateinamen inkl. Backslashes übergeben,
und auch Umlaute in den Pfaden können natürlich vorkommen (und kommen auch).

Ich musste da allerdings keinerlei Klimmzüge oder Umwandlungen machen, um das fehlerfrei zu bewerkstelligen.

Kannst du mal einen 10-Zeiler machen, der das Problem zeigt (inkl. Tabellenerstellung)?
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von hschmidt »

HeX0R hat geschrieben:...Kannst du mal einen 10-Zeiler machen, der das Problem zeigt (inkl. Tabellenerstellung)?
Hallo HeX0R,

danke für Dein Hilfsangebot. Anbei habe ich ein kleines Testprogramm und die DB-Struktur als SQL-Code erstellt.
Es scheint in erster Linie das einfache Anführungszeichen zu sein, welches die Probleme bereitet (und natürlich \). Wenn ich beide Zeichen per vorgestelltem Backslash "escape", dann funktioniert es mit MEINEN Beispielnamen.

Code: Alles auswählen

myDatabaseName.s = ReadPreferenceString("name", "pgdatabase")
myDatabasePort.s = ReadPreferenceString("port", "5432")
myDatabaseHost.s = ReadPreferenceString("host", "192.168.10.110")
		
UsePostgreSQLDatabase()

; myFilename.s = OpenFileRequester("Select file", "./", "*.*", 0,#PB_Requester_MultiSelection)

; Dateiname wird eingetragen, jedoch ohne Backslashs - Umlaute OK
; myFilename.s = "C:\Dokumente und Einstellungen\horst\test123äöüß.jpg"

; Dateiname wird eingetragen, Umlaute OK, Backslashs escaped - soweit brauchbar
; myFilename.s = "C:\Dokumente und Einstellungen\horst\test123äöüß.jpg"
; myFilename = ReplaceString(myFilename, "\", "\\")

; Dateiname wird nicht eingetragen, in diesem Fall aufgrund des ' -Zeichens
; myFilename.s = "C:\Dokumente und Einstellungen\horst\Verückter '~# Name.jpg"

; Dateiname wird eingetragen, ' und \ escaped - Doch welche Überraschungen kommen noch ...
myFilename.s = "C:\Dokumente und Einstellungen\horst\Verückter '~# Name.jpg"
myFilename = ReplaceString(myFilename, "\", "\\") ; escape \
myFilename = ReplaceString(myFilename, "'", "\'") ; escape '

tmpDatabaseName.s = "host="+myDatabaseHost+" port="+myDatabasePort+" dbname="+myDatabaseName
If OpenDatabase(1, tmpDatabaseName, "postgres", "mypassword", #PB_Database_PostgreSQL)
     sql.s = "INSERT INTO mytable (url) VALUES ('" + myFilename + "')"   
     If DatabaseUpdate(1, sql)
          FinishDatabaseQuery(1)
     Else
          MessageRequester("ERROR", "No INSERT") : End
     EndIf
     CloseDatabase(1)
Else
	MessageRequester("ERROR","No database connection") : End
EndIf
Postgresql-DB und Tabelle (Beispiel)

Code: Alles auswählen

CREATE DATABASE pgdatabase
  With OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       CONNECTION LIMIT = -1;
       
CREATE TABLE mytable
(
  id integer Not NULL Default nextval('"myTable_id_seq"'::regclass),
  url text,
  CONSTRAINT pk_id PRIMARY KEY (id)
)
With (
  OIDS=FALSE
);
ALTER TABLE mytable OWNER To postgres;
Könnte ich mir sicher sein, dass nur diese beiden Zeichen (',\) relevant sind, dann wäre es ja ok.
Doch der Otto-Normal-User denkt sich manchmal die unmöglichsten Dateinamen aus, so dass mir später die Sache doch nochmal auf die Füße fällt (zumal auch chinesische, thailändische usw. Zeichen enthalten sein können).
Mir wäre da eine "saubere" Methode lieber, einen Text/URL/Dateiname richtig in die PostgreSQL-Tabelle zu schreiben.

Vielleicht hat noch jemand eine Idee.
Besten Dank nochmal,
Horst
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: PostgreSQL-Datensatz und Sonderzeichen ...

Beitrag von Kiffi »

hschmidt hat geschrieben:Vielleicht hat noch jemand eine Idee.
bzgl. der einfachen Hochkommata: Einfach verdoppeln. Das muss
Du ohnehin für jedes DBS machen (auch SQLite beispielsweise).

Code: Alles auswählen

myFilename = ReplaceString(myFilename, "'", "''") 
Grüße ... Kiffi
Hygge
Antworten