我有一个文本文件,其中包含几个十六进制字符串:
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
任何想法,或者我是否接近错误?
答案 0 :(得分:70)
您可以使用decode
函数将十六进制字符串转换为bytea(其中“encoding”表示将二进制值编码为某个文本值)。例如:
select decode('DEADBEEF', 'hex');
decode
------------------
\336\255\276\357
使用9.0的默认输出更容易理解:
decode
------------
\xdeadbeef
你不能只说E'\xDE\xAD\xBE\xEF'
的原因是这是为了创建一个文本值而不是bytea,所以Postgresql会尝试将它从客户端编码转换为数据库编码。您可以像这样编写bytea转义格式,但需要加倍反斜杠:E'\\336\\255\\276\\357'::bytea
。我想你可以看到为什么bytea格式被改变了....恕我直言decode()
函数是一种写入输入的合理方式,即使涉及到一些开销。
答案 1 :(得分:27)
INSERT INTO mytable (testcol) VALUES (decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'))
答案 2 :(得分:5)
我最近需要从/向Postgres读取/写入二进制数据,但是通过Ruby。以下是我使用Pg library进行的操作。
虽然不是严格遵循Postgres,但我认为我会将这个以Ruby为中心的答案包含在内以供参考。
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) }
答案 3 :(得分:1)
这是更新后的答案,其中包括如何插入以及如何查询。
可以使用decode
函数将十六进制转换为bytea值。这应该同时用于查询和插入。
这既可以用于插入,也可以用于查询。
SELECT * FROM mytable WHERE testcol = (decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'));
用户询问了以下内容:
插入后如何按十六进制值搜索BYtea字段?
SELECT * FROM my_table WHERE myHexField = (encode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'));
不起作用。
在文档Binary String Functions and Operators中,它们同时描述了encode
和decode
。
+==================================+=============+=======================================================================================================+=======================================+============+
| Function | Return Type | Description | Example | Result |
+==================================+=============+=======================================================================================================+=======================================+============+
| decode(string text, format text) | bytea | Decode binary data from textual representation in string. Options for format are same as in encode. | decode('123\000456', 'escape') | 123\000456 |
+----------------------------------+-------------+-------------------------------------------------------------------------------------------------------+---------------------------------------+------------+
| encode(data bytea, format text) | text | Encode binary data into a textual representation. Supported formats are: base64, hex, escape. escape | encode('123\000456'::bytea, 'escape') | 123\000456 |
| | | converts zero bytes and high-bit-set bytes to octal sequences (\nnn) and doubles backslashes. | | |
+----------------------------------+-------------+-------------------------------------------------------------------------------------------------------+---------------------------------------+------------+
因此,您会注意到Encode
用于encoding binary data into a textual string
并返回文本。但是,由于我们存储的是bytea
,因此插入和查询都必须使用decode
。
create table mytable (testcol BYTEA);
INSERT INTO
mytable (testcol)
VALUES
(decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'));
发件人:请参见previous answer
答案 4 :(得分:0)