Вставка текстовой строки с шестнадцатеричным в PostgreSQL в качестве байты - PullRequest
41 голосов
/ 23 июня 2010

У меня есть текстовый файл с несколькими шестнадцатеричными строками:

013d7d16d7ad4fefb61bd95b765c8ceb
007687fc64b746569616414b78c81ef1

Я бы хотел сохранить их в базе данных как bytea вместо varchar . То есть я хотел бы, чтобы база данных хранила 01 как один байт 00000001, а не символы «0» и «1».

Я могу легко запустить этот файл через sed, чтобы отформатировать / экранировать его любым удобным для меня способом.

Вот что я пробовал:

create table mytable (testcol BYTEA);

Это работает:

insert into mytable (testcol) values (E'\x7f\x7f');

Однако, как только у меня появляется байт, превышающий \ x7f, я получаю эту ошибку:

insert into mytable (testcol) values (E'\x7f\x80');
ERROR:  invalid byte sequence for encoding "UTF8": 0x80

Есть какие-нибудь идеи, или я не так подхожу?

Ответы [ 4 ]

71 голосов
/ 23 июня 2010

Вы можете преобразовать шестнадцатеричную строку в bytea, используя функцию decode (где «кодировка» означает кодирование двоичного значения в некоторое текстовое значение).Например:

select decode('DEADBEEF', 'hex');
      decode      
------------------
 \336\255\276\357

, что более понятно при выводе по умолчанию 9.0:

   decode   
------------
 \xdeadbeef

Причина, по которой вы не можете просто сказать E'\xDE\xAD\xBE\xEF', заключается в том, чтотекстовое значение, а не bytea, поэтому Postgresql попытается преобразовать его из кодировки клиента в кодировку базы данных.Вы могли бы написать такой escape-формат bytea, но вам нужно удвоить обратную косую черту: E'\\336\\255\\276\\357'::bytea.Я думаю, вы можете понять, почему формат байта изменяется ... ИМХО функция decode() - это разумный способ записи входных данных, даже если есть некоторые накладные расходы.

27 голосов
/ 23 июня 2010
INSERT INTO
  mytable (testcol)
VALUES
  (decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'))
5 голосов
/ 09 сентября 2013

Рубиновый Путь

Недавно мне нужно было читать / записывать двоичные данные из / в Postgres, но через Ruby. Вот как я это сделал, используя библиотеку Pg .

Хотя это и не является строго специфичным для Postgres, я подумал, что для справки я бы включил этот Ruby-ориентированный ответ.

Настройка Postgres DB

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) }
0 голосов
/ 19 апреля 2018

Больше и все остальные опции :

-- 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...