it-swarm.com.de

Einfügen eines Textstrings mit Hex in PostgreSQL als Bytea

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?

38
Donald Miner

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.

64
araqnid
EINFÜGEN IN
 mytable (testcol) 
 WERTE 
 (decodieren ('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'))
22
Julius Musseau

Der Ruby-Weg

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.

Postgres DB Setup

require 'pg'
DB = PG::Connection.new(Host: 'localhost', dbname:'test')
DB.exec "CREATE TABLE mytable (testcol BYTEA)"
BINARY = 1

Fügen Sie binäre Daten ein

sql = "INSERT INTO mytable (testcol) VALUES ($1)"
param = {value: binary_data, format: BINARY}
DB.exec_params(sql, [param]) {|res| res.cmd_tuples == 1 }

Wählen Sie Binärdaten aus

sql = "SELECT testcol FROM mytable LIMIT 1"
DB.exec_params(sql, [], BINARY) {|res| res.getvalue(0,0) }
5
Clint Pachl

Weitere und diverse Optionen :

-- insert 123[char of value zero]abc456
insert into mytable (testcol) values decode(E'123\\000abc456', 'escape');

-- insert abc456
insert into mytable (testcol) values decode('YWJjNDU2', 'base64');
0
rogerdpack