二进制(原生)数据

可使用 NATIVE 解析器选项加载二进制数据,不支持此选项的 COPY LOCAL 除外。由于二进制格式数据不需要使用和处理分隔符,因此无需将整数、日期和时间戳从文本转换成本机存储格式,与分隔的数据相比,其加载性能更佳。所有二进制格式文件都必须符合附录:创建原生二进制格式文件中描述的格式规范。

本机二进制格式数据文件通常比其分隔文本格式的数据文件要大,所以在加载之前需先压缩数据。NATIVE 解析器不支持串联的压缩二进制文件。开发 ETL 应用程序插件时,您可以加载本机(二进制)格式文件。

逐字节加载二进制数据时无格式复制,因为数据中的列和记录分隔符必须进行转义。二进制数据类型值会填充到输入、受支持的函数、操作符以及类型转换中并进行转换。

加载十六进制、八进制和位字符串数据

可以仅使用十六进制、八进制和位字符串格式来加载二进制列。若要指定这些列格式,请使用 COPY 语句的 FORMAT 选项:

  • 十六进制

  • 八进制

  • 位字符串

以下示例说明如何使用 FORMAT 选项。

  1. 创建一个表:

    => CREATE TABLE t(oct VARBINARY(5),
         hex VARBINARY(5),
         bitstring VARBINARY(5) );
    
  2. 创建投影:

    => CREATE PROJECTION t_p(oct, hex, bitstring) AS SELECT * FROM t;
    
  3. 使用带有 STDIN 子句的 COPY 语句并指定每个格式:

    => COPY t (oct FORMAT 'octal', hex FORMAT 'hex',
               bitstring FORMAT 'bitstring')
       FROM STDIN DELIMITER ',';
    
  4. 在单独一行中输入要加载的数据,以反斜杠 () 和句点 (.) 结束语句:

    Enter data to be copied followed by a newline.
    End with a backslash and a period on a line by itself.
    >> 141142143144145,0x6162636465,0110000101100010011000110110010001100101
    >> \.
    
  5. 对表 t 使用选择查询以查看输入值结果:

    => SELECT * FROM t;
     oct   | hex   | bitstring
    -------+-------+-----------
    abcde  | abcde | abcde
    (1 row)
    

COPY 使用与输入二进制数据所用格式相同的默认格式来加载二进制数据。由于反斜杠字符 ('\\') 为默认转义字符,因此必须对八进制输入值进行转义。例如,将字节 '\141' 输入为 '\\\141'

在输入中,COPY 按如下方式转换字符串数据:

这两个函数都使用 VARCHAR 实参并返回 VARBINARY 值。

也可以使用转义字符通过转义两次来表示(十进制)字节 92;例如 '\\\\\\'。请注意,vsql 以四个反斜杠输入转义的反斜杠。等效输入为十六进制值 '0x5c' 和八进制值 '\134' (134 = 1 x 8^2 + 3 x 8^1 + 4 x 8^0 = 92)。

您可以加载使用反斜杠转义后的分隔符值。例如,假定分隔符为 '|''\\\001\\|\\\002' 则被加载为 {1,124,2},也可以采用八进制格式将其表示成 '\\\001\\\174\\\002'

如果插入值的字节数太多,以致于目标列容纳不下,COPY 将会返回错误。例如,如果列 c1VARBINARY(1)

=> INSERT INTO t (c1) values ('ab');   ERROR: 2-byte value too long for type Varbinary(1)

如果您对字节数过多以致于目标数据类型容纳不下的值进行隐式或显式类型转换,COPY 则会截断该数据而不进行提示。例如:

=> SELECT 'abcd'::binary(2);
 binary
--------
 ab
(1 row)

十六进制数据

可选的 '0x' 前缀指示值为十六进制而非十进制,但并非所有十六进制值都使用 A-F;例如 5396。在加载输入数据时,COPY 将忽略 0x 前缀。

如果十六进制值中存在奇数个字符,则将第一个字符处理为第一个(最左边)字节的低效半字节。

八进制数据

加载八进制格式数据要求使用三个数字的八进制代码表示每个字节。第一个数字必须在 [0,3] 范围内,第二个和第三个数字必须同时在 [0,7] 范围内。

如果某个八进制值的长度不是三的倍数,或者三个数字中有一个不在正确范围内,该值则无效,COPY 将拒绝该值所在的行。如果提供的八进制值无效,COPY 将会返回错误。例如:

=> SELECT '\\000\\387'::binary(8);
ERROR: invalid input syntax for type binary

如果行包含具有无效八进制表示的二进制值,则也会被拒绝。例如,COPY 会拒绝 '\\\008',因为 '\\\ 008' 不是有效的八进制数字。

位字符串数据

加载位字符串数据要求每个字符必须是零 (0) 或一 (1),值必须是八个字符的倍数。如果位字符串值不是八个字符的倍数,COPY 则会将前 n 个字符视为第一个(最左端)字节的低位,其中 n 为值长度除以八之后的余数。

示例

以下示例显示了 VARBINARY HEX_TO_BINARY(VARCHAR)VARCHAR TO_HEX(VARBINARY) 的用法。

  1. 创建带有二进制列的表 t 及其投影:

    => CREATE TABLE t (c BINARY(1));
    => CREATE PROJECTION t_p (c) AS SELECT c FROM t;
    
  2. 插入最小和最大字节值,包括以字符串表示的 IP 地址:

    => INSERT INTO t values(HEX_TO_BINARY('0x00'));
    => INSERT INTO t values(HEX_TO_BINARY('0xFF'));
    => INSERT INTO t values (V6_ATON('2001:DB8::8:800:200C:417A'));
    

    使用 TO_HEX 函数在输出中以十六进制设置二进制值的格式:

    => SELECT TO_HEX(c) FROM t;
     to_hex
    --------
     00
     ff
     20
    (3 rows)
    

另请参阅