2、SQL Server产生数据
然后通过java程序进行获取数据并插入到PG,同样会得到错误信息:
首先我们认为此为gb2312转化到UTF8时,发生了无法转化的错误。经查UTF8是变长的, 1-6个字节。他的编码规则如下:
Bits Last code point Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 7 U+007F 0xxxxxxx 11 U+07FF 110xxxxx 10xxxxxx 16 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx 21 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 26 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 31 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
而0x00是符合UTF8规则的。这就使我们非常诧异。然后我们发现有两点继而确认了问题: 1、
2、
Terminating character
Indicated by
Tab
\t
This is the default field terminator.
Newline character
\n
This is the default row terminator.
Carriage return/line feed
\r
Backslash1
\\
Null terminator (nonvisible terminator)2
\0
Any printable character (control characters are not printable, except null, tab, newline, and carriage return)
(*, A, t, l, and so on)
String of up to 10 printable characters, including some or all of the terminators listed earlier
(**\t**, end, !!!!!!!!!!, \t—\n, and so on)
Source:http://msdn.microsoft.com/en-us/library/ms191485.aspx
由此我们确定,是pg对null的处理和SQL Server处理是不相同的,所以在这里出现了错误。
而导致这一问题的PG具体代码如下(src/backend/utils/mb/wchar.c的pg_verify_mbstr_len):
report_invalid_encoding函数是将错误信息返回,也就是
invalid byte sequence for encoding "UTF8": 0x00 而真正导致这一问题的就是: !IS_HIGHBIT_SET(*mbstr)当*mbstr为0x00时进入判断,然后进而判断*mbstr是否为\0,当为\0时,直接进入函数report_invalid_encoding报错。
所以出现此问题的原因是PG和SQL Server对null的处理是不相同的。
处理方案 :
1、将SQL Server源数据进行修改方法,
2、对应用进行修改,获取到SQL Server数据时,将数据进行转化,和第一种方法异曲同工。