我使用的应用程序将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
简而言之,二进制字符串适合存储数据 程序员认为是“原始字节”,而字符串则是 适合存储文本。
我不确定在这种情况下我做错了什么,因为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
,直到找到其他内容。