代码之家  ›  专栏  ›  技术社区  ›  Donald Miner

在PostgreSQL中插入十六进制文本字符串作为bytea

  •  39
  • Donald Miner  · 技术社区  · 14 年前

    013d7d16d7ad4fefb61bd95b765c8ceb
    007687fc64b746569616414b78c81ef1
    

    我想把这些存储在数据库中作为 二进制数据 ,而不是 . 也就是说,我希望数据库将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 回复  |  直到 14 年前
        1
  •  84
  •   araqnid    14 年前

    decode 函数(其中“编码”表示将二进制值编码为某个文本值)。例如:

    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()

        2
  •  35
  •   Julius Musseau    14 年前
    我的表格(testcol)
    价值观
    
        3
  •  7
  •   Clint Pachl    11 年前

    我最近需要通过Ruby从Postgres读写二进制数据。下面是我如何使用 Pg library

    虽然不是严格针对Postgres的,但是我想我应该包括这个以Ruby为中心的答案作为参考。

    Postgres数据库设置

    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) }
    
        4
  •  1
  •   Menelaos    4 年前

    介绍

    可以使用 decode 功能。这应该用于查询和插入。

    Example SQL Fiddle

    SELECT * FROM mytable WHERE testcol = (decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'));
    

    编码vs解码查询

    有用户提出以下问题:

    SELECT * FROM my_table WHERE myHexField =
    (encode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'));
    

    不起作用。

    在文档中 Binary String Functions and Operators ,它们都有描述 encode

       +==================================+=============+=======================================================================================================+=======================================+============+
        |             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 我们必须使用 解码 用于插入和查询。

    插入

    create table mytable (testcol BYTEA);
    
    INSERT INTO
      mytable (testcol)
    VALUES
      (decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'));
    

    previous answer

        5
  •  0
  •   rogerdpack Blair Conrad    4 年前

    More 杂七杂八 options 哪里 testcol 属于类型 bytea :

    -- how to insert the string "123[a char of value zero]abc456"
    insert into mytable (testcol) values decode(E'123\\000abc456', 'escape');
    
    -- how to insert the string "123abc456"
    insert into mytable (testcol) values decode(E'123abc456', 'escape');
    
    -- how to insert in base64: insert string "abc456"
    insert into mytable (testcol) values decode('YWJjNDU2', 'base64');