J'ai un fichier texte avec plusieurs chaînes d'hex:
013d7d16d7ad4fefb61bd95b765c8ceb
007687fc64b746569616414b78c81ef1
Je voudrais les stocker dans la base de données en tant que bytea , au lieu de varchar . C'est-à-dire que j'aimerais que la base de données stocke 01 sous le seul octet 00000001, et non les caractères "0" et "1".
Je peux facilement exécuter ce fichier via sed pour le formater/l’échapper par tous les moyens.
C'est ce que j'ai essayé:
create table mytable (testcol BYTEA);
Cela marche:
insert into mytable (testcol) values (E'\x7f\x7f');
Cependant, dès que j'ai un octet supérieur à\x7f, j'obtiens cette erreur:
insert into mytable (testcol) values (E'\x7f\x80');
ERROR: invalid byte sequence for encoding "UTF8": 0x80
Des idées, ou est-ce que j'aborde les choses mal?
Vous pouvez convertir une chaîne hexadécimale en octets en utilisant la fonction decode
(où "encoding" signifie coder une valeur binaire en une valeur textuelle). Par exemple:
select decode('DEADBEEF', 'hex');
decode
------------------
\336\255\276\357
ce qui est plus compréhensible avec la sortie par défaut de la 9.0:
decode
------------
\xdeadbeef
La raison pour laquelle vous ne pouvez pas simplement dire E'\xDE\xAD\xBE\xEF'
est que cela est destiné à créer une valeur textuelle, pas un bytea, donc Postgresql essaiera de la convertir du codage client en codage de base de données. Vous pouvez écrire le format d'échappement bytea de cette manière, mais vous devez doubler les barres obliques inverses: E'\\336\\255\\276\\357'::bytea
. Je pense que vous pouvez voir pourquoi le format bytea est en train d'être modifié ... IMHO, la fonction decode()
est un moyen raisonnable d'écrire des entrées, même s'il y a une surcharge.
INSÉRER DANS mytable (testcol) VALEURS (décode ('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'))
J'ai récemment eu besoin de lire/écrire des données binaires de/vers Postgres, mais via Ruby. Voici comment je l'ai fait en utilisant la bibliothèque Pg .
Bien que n'étant pas strictement spécifique à Postgres, je pensais inclure cette réponse centrée sur Ruby à titre de référence.
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) }