Ich habe eine Textdatei mit mehreren Hex-Strings darin:
013d7d16d7ad4fefb61bd95b765c8ceb
007687fc64b746569616414b78c81ef1
Ich möchte diese in der Datenbank als bytea anstelle von varchar speichern. Das heißt, ich möchte, dass die Datenbank 01 als Einzelbyte 00000001 speichert, nicht als Zeichen '0' & '1'.
Ich kann diese Datei leicht durch sed laufen lassen, um sie auf jede Art und Weise zu formatieren, die ich brauche.
Das habe ich versucht:
create table mytable (testcol BYTEA);
Das funktioniert:
insert into mytable (testcol) values (E'\x7f\x7f');
Sobald ich jedoch ein Byte habe, das über\x7f geht, erhalte ich diesen Fehler:
insert into mytable (testcol) values (E'\x7f\x80');
ERROR: invalid byte sequence for encoding "UTF8": 0x80
Irgendwelche Ideen, oder nähere ich mich den Dingen?
Sie können einen Hex-String mit der Funktion decode
in Bytea konvertieren (wobei "Kodierung" bedeutet, dass ein Binärwert in einen Textwert codiert wird). Zum Beispiel:
select decode('DEADBEEF', 'hex');
decode
------------------
\336\255\276\357
was mit der Standardausgabe von 9.0 verständlicher ist:
decode
------------
\xdeadbeef
Der Grund, aus dem Sie nicht einfach E'\xDE\xAD\xBE\xEF'
sagen können, besteht darin, dass dies einen Textwert und nicht einen Bytea-Wert ergeben soll. Daher versucht Postgresql, ihn aus der Clientcodierung in die Datenbankcodierung zu konvertieren. Sie könnten das Bytea-Escape-Format so schreiben, aber Sie müssen die umgekehrten Schrägstriche verdoppeln: E'\\336\\255\\276\\357'::bytea
. Ich denke, Sie können sehen, warum das Bytea-Format geändert wird ... IMHO ist die Funktion decode()
eine vernünftige Möglichkeit, Eingaben zu schreiben, auch wenn ein gewisser Aufwand besteht.
EINFÜGEN IN mytable (testcol) WERTE (decodieren ('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'))
Vor kurzem musste ich binäre Daten von/nach Postgres lesen/schreiben, jedoch über Ruby. So habe ich es mit der Pg-Bibliothek gemacht.
Obwohl nicht streng postgresspezifisch, dachte ich, ich würde diese Ruby-zentrierte Antwort als Referenz hinzufügen.
require 'pg'
DB = PG::Connection.new(Host: 'localhost', dbname:'test')
DB.exec "CREATE TABLE mytable (testcol BYTEA)"
BINARY = 1
sql = "INSERT INTO mytable (testcol) VALUES ($1)"
param = {value: binary_data, format: BINARY}
DB.exec_params(sql, [param]) {|res| res.cmd_tuples == 1 }
sql = "SELECT testcol FROM mytable LIMIT 1"
DB.exec_params(sql, [], BINARY) {|res| res.getvalue(0,0) }