PostgreSQL:如何使用GnuCOBOL将不兼容(UTF8)原始字节存储为bytea?

时间:2018-04-24 13:03:45

标签: postgresql utf-8 gnucobol

我使用的应用程序将32位掩码(1和0)存储为数据库中的4字符字段,方法是将其转换为十六进制。 (它是一个非常古老的应用程序,所以不能改变它。)

这曾经与Oracle& DB2(UTF8编码),但是当我尝试使用COBOL程序插入值时,使用PostgreSQL(UTF8编码),它会产生以下错误:

ERROR: invalid byte sequence for encoding "SJIS": 0xa0

Binary = 01101000001001110000110010100000

Hex=0x68270CA0

数据库编码&表格定义

diginst=> \encoding
UTF8
diginst=> \d tab_1
 Column |     Type     | Collation | Nullable | Default
--------+--------------+-----------+----------+---------
 code   | character(5) |           | not null |
 mask   | bytea        |           |          |

COBOL计划

   IDENTIFICATION              DIVISION.
   PROGRAM-ID.                 ENCODE.
   DATE-WRITTEN.               2013-06-28.
   DATA                        DIVISION.
   WORKING-STORAGE             SECTION.

       EXEC SQL BEGIN DECLARE SECTION END-EXEC.
   01  DBNAME                PIC  X(30) VALUE SPACE.
   01  SOC-REC-VARS.
       05  D-CODE             PIC X(5).
       05  D-MASK             PIC X(4).
       EXEC SQL END DECLARE SECTION END-EXEC.

       EXEC SQL INCLUDE SQLCA END-EXEC.

   PROCEDURE                   DIVISION.
   MAIN-RTN.
       MOVE  "/@diginst"         TO   DBNAME.
       EXEC SQL
           CONNECT :DBNAME
       END-EXEC.
       IF  SQLCODE NOT = ZERO DISPLAY "ERROR CONNECTING".
       MOVE "00001" TO D-CODE.
       MOVE X"68270CA0" TO D-MASK.

       EXEC SQL
         INSERT INTO TAB_1
         (CODE,
          MASK)
         VALUES(:D-CODE,
                :D-MASK)
       END-EXEC.
       IF SQLCODE = ZERO DISPLAY "INSERT SUCCESSFUL"
       ELSE DISPLAY "INSERT FAILED " SQLERRMC
            GO TO EXIT-0.
       EXEC SQL
          SELECT CODE,MASK
                 INTO :D-CODE, :D-MASK FROM TAB_1
       END-EXEC.
       IF SQLCODE = ZERO DISPLAY "SELECT SUCCESSFUL"
       ELSE DISPLAY "SELECT FAILED " SQLERRMC.
   EXIT-0.
       STOP RUN.

不确定为什么它将编码选为SJIS,即使client_encoding和server_encoding是UTF8。但是,即使它是UTF8(我在上面的代码中手动执行SET CLIENT_ENCODING TO'UTF8'),0xA0也不是UTF8字符集中的有效字符。

来自bytea

上的PostgreSQL文档
  

简而言之,二进制字符串适合存储数据   程序员认为是“原始字节”,而字符串则是   适合存储文本。

我不确定在这种情况下我做错了什么,因为bytea应该起作用(根据文档)。

还想知道为什么程序应该SJIS时将默认编码选为UTF8。我也尝试设置环境变量PGCLIENTENCODING=UTF8,但它仍然提供与SJIS相同的错误。

*没想到要问另外一个问题,因为我认为这也与主要问题有关。

更新:经过一些挖掘后,DB2通过在create table语句中添加子句FOR BIT DATA来存储原始字节(即使db编码不支持它)as- < / p>

create table tab_db2 (key_part char(5) not null, raw_data char (100) for bit data); 

在Oracle中,使用的字符集为AL32UTF8,支持更多字符(supplementary characters),然后UTF8

PostgreSQL中为AL32UTF8设置了no equivalent个字符集,所以我暂时使用LATIN1,直到找到其他内容。

0 个答案:

没有答案