我有一个文本文件,其中包含几个十六进制字符串:
013d7d16d7ad4fefb61bd95b765c8ceb
007687fc64b746569616414b78c81ef1
Run Code Online (Sandbox Code Playgroud)
我想将它们作为bytea存储在数据库中,而不是varchar.也就是说,我希望数据库将01存储为单字节00000001,而不是字符'0'和'1'.
我可以通过sed轻松运行这个文件,以任何方式格式化/转义它.
这是我尝试过的:
create table mytable (testcol BYTEA);
Run Code Online (Sandbox Code Playgroud)
这有效:
insert into mytable (testcol) values (E'\x7f\x7f');
Run Code Online (Sandbox Code Playgroud)
但是,只要我的字节超过\ x7f,我就会收到此错误:
insert into mytable (testcol) values (E'\x7f\x80');
ERROR: invalid byte sequence for encoding "UTF8": 0x80
Run Code Online (Sandbox Code Playgroud)
任何想法,还是我接近错误?
ara*_*nid 73
您可以使用decode
函数将十六进制字符串转换为bytea (其中"encoding"表示将二进制值编码为某个文本值).例如:
select decode('DEADBEEF', 'hex');
decode
------------------
\336\255\276\357
Run Code Online (Sandbox Code Playgroud)
使用9.0的默认输出更容易理解:
decode
------------
\xdeadbeef
Run Code Online (Sandbox Code Playgroud)
你不能只说的原因E'\xDE\xAD\xBE\xEF'
是这是为了创建一个文本值,而不是一个bytea,所以Postgresql会尝试将它从客户端编码转换为数据库编码.您可以像这样编写bytea转义格式,但需要加倍反斜杠:E'\\336\\255\\276\\357'::bytea
.我想你可以看到为什么bytea格式正在被改变....恕我直言这个decode()
函数是一种写入输入的合理方式,即使涉及到一些开销.
Jul*_*eau 28
INSERT INTO mytable (testcol) VALUES (decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'))
这是更新的答案,包括如何插入以及如何查询。
\n可以使用该decode
函数将十六进制转换为字节值。这应该用于查询和插入。
这既可用于插入,也可用于查询。
\n\nSELECT * FROM mytable WHERE testcol = (decode(\'013d7d16d7ad4fefb61bd95b765c8ceb\', \'hex\'));\n
Run Code Online (Sandbox Code Playgroud)\n一位用户提出了以下问题:
\n\n\n插入后如何通过十六进制值搜索bytea字段?
\nRun Code Online (Sandbox Code Playgroud)\nSELECT * FROM my_table WHERE myHexField =\n(encode(\'013d7d16d7ad4fefb61bd95b765c8ceb\', \'hex\'));\n
不起作用。
\n
在文档Binary String Functions and Operatorsencode
中,有和的描述decode
。
+==================================+=============+=======================================================================================================+=======================================+============+\n | Function | Return Type | Description | Example | Result |\n +==================================+=============+=======================================================================================================+=======================================+============+\n | decode(string\xc2\xa0text,\xc2\xa0format\xc2\xa0text) | bytea | Decode binary data from textual representation in\xc2\xa0string. Options for\xc2\xa0format\xc2\xa0are same as in\xc2\xa0encode. | decode(\'123\\000456\', \'escape\') | 123\\000456 |\n +----------------------------------+-------------+-------------------------------------------------------------------------------------------------------+---------------------------------------+------------+\n | encode(data\xc2\xa0bytea,\xc2\xa0format\xc2\xa0text) | text | Encode binary data into a textual representation. Supported formats are:\xc2\xa0base64,\xc2\xa0hex,\xc2\xa0escape.\xc2\xa0escape\xc2\xa0 | encode(\'123\\000456\'::bytea, \'escape\') | 123\\000456 |\n | | |\xc2\xa0converts zero bytes and high-bit-set bytes to octal sequences (\\nnn) and doubles backslashes. | | |\n +----------------------------------+-------------+-------------------------------------------------------------------------------------------------------+---------------------------------------+------------+\n
Run Code Online (Sandbox Code Playgroud)\n所以你会注意到它Encode
是用于encoding binary data into a textual string
并返回文本。但是,由于我们要存储,因此bytea
必须decode
同时用于插入和查询。
create table mytable (testcol BYTEA);\n\nINSERT INTO\n mytable (testcol)\nVALUES\n (decode(\'013d7d16d7ad4fefb61bd95b765c8ceb\', \'hex\'));\n
Run Code Online (Sandbox Code Playgroud)\n出自:见之前的回答
\n我最近需要从/向Postgres读取/写入二进制数据,但是通过Ruby.这是我使用Pg库的方式.
虽然不是严格遵循Postgres,但我认为我会将这个以Ruby为中心的答案包含在内以供参考.
require 'pg'
DB = PG::Connection.new(host: 'localhost', dbname:'test')
DB.exec "CREATE TABLE mytable (testcol BYTEA)"
BINARY = 1
Run Code Online (Sandbox Code Playgroud)
sql = "INSERT INTO mytable (testcol) VALUES ($1)"
param = {value: binary_data, format: BINARY}
DB.exec_params(sql, [param]) {|res| res.cmd_tuples == 1 }
Run Code Online (Sandbox Code Playgroud)
sql = "SELECT testcol FROM mytable LIMIT 1"
DB.exec_params(sql, [], BINARY) {|res| res.getvalue(0,0) }
Run Code Online (Sandbox Code Playgroud)