金仓数据库KingbaseES “requested character too large”错误分析

一、适用范围

本文档适用于KingbaseES所有版本。

二、问题现象

使用从其他数据库迁移到KingbaseES数据库的自定义函数、存储过程、Package包..出现以下错误信息:

错误:所请求的字符太大
ERROR: requested character too large

三、原因分析

1.报错环境的KingbaseES数据库字符集为GBK,目前不支持使用ASCII取中文值。

2.数据库自定义函数、存储过程、Package包里面有使用ASCII函数。

3.在GBK环境使用自定义函数、存储过程、Package包传入参数包含中文或者全角字符。

四、解决方法

1.对传入参数的字符串进行过滤,只取数字或者英文字符

参考以下函数进行改写处理:

CREATE OR REPLACE FUNCTION FUNC_GETLASTNUMBER2(STR TEXT) RETURNS TEXT AS $$
 DECLARE I INT=0;
 LENSTR INT=LENGTH(STR);
 STR1 TEXT ;
 STRRE TEXT ='';
 STRREOR INTEGER =0;
BEGIN
 WHILE I<=LENSTR LOOP 
  --STR1=SUBSTRING(STR,I,1);  --原始函数使用substring,改为substrb就可以过滤掉中文或者全角字符
  STR1=SUBSTRB(STR,I,1);
  IF(ASCII(STR1)>=48 AND ASCII(STR1)<=57) THEN 
    IF(STRREOR=1) THEN 
        STRRE='';
        STRREOR=0;
    END IF;
    STRRE=STRRE || STR1;
  ELSE
  STRREOR=1;---进入了非数字检索
  -- SET STRRE=''
  END IF; 
   I=I+1;
  END LOOP;
 RETURN(STRRE);
END;
$$LANGUAGE PLPGSQL;


SELECT * FROM func_getlastnumber2('00000000收拾.获取;?');
 func_getlastnumber2 
---------------------
 000000000
(1 row)

注意:substr、substrb、substring函数的区别

以KingbaseES数据库UTF8编码为例(1个汉字占3个字节,GBK编码1个汉字占2个字节):

cmc=# select substr('KingbaseES数据库',11,3),substrb('KingbaseES数据库',11,3),substring('KingbaseES数据库',11,3);
 substr | substrb | substring 
--------+---------+-----------
 数据库 | 数      | 数据库

 #使用 substrb 截取长度为3的字符串时,只能截取到一个字符,而使用substr、substring可以截取到三个字符。

差异:

substr 按字符截取

substrb 按字节截取

substring 按字符截取

2.使用ASCII函数对传入的中文字符串全角字符转半角字符

参考以下函数进行改写处理:

CREATE FUNCTION hex_to_dec(in_hex TEXT)
RETURNS INT
IMMUTABLE STRICT LANGUAGE sql AS
$body$
  SELECT CAST(CAST(('x' || CAST($1 AS text)) AS bit(8)) AS INT);
$body$;

create or replace Function Trimall(v_Str Varchar2) Return String Is
    --将全角字符转换为半角字符,统一输出格式
    v_Retval Varchar2(4000) := '';
    c        Varchar2(4) := ''; --当前字节
    Cc       Varchar2(10) := ''; --当前双字节
    c_Code   Number(8); --当前字节ascii码(十进制)
    Code1    Number;
    Code2    Number;
    n_Loop   Number(4);
    n_Len    Number(8);
    Begin
      n_Loop := 1;
      n_Len  := Lengthb(v_Str);
      While n_Loop <= n_Len loop
          --c      := Substrb(v_Str, n_Loop, 1);
        c      := sys.Substrb(v_Str, n_Loop, 1);     --在有kdb_orafce插件的时候,指定sys.Substrb进行处理。
          --c      := encode(Substrb(v_Str, n_Loop, 1)::bytea,'hex');  --在有kdb_orafce插件的时候,可以用此函数处理。
        Cc     := Substrb(v_Str, n_Loop, 2);
        --c := ' ';
        c_Code := Ascii(c); --获取当前字节ascii码(十进制)
        Code1  := hex_to_dec(Substr(replace(utl_raw.cast_to_raw(Cc),'\x',''), 1, 2)); 
        Code2  := hex_to_dec(Substr(replace(utl_raw.cast_to_raw(Cc),'\x',''), 3, 2)); 
        If c_Code = Code1 Then
          --单字节字符
          v_Retval := v_Retval || c;
          n_Loop   := n_Loop + 1;
        Elsif Code1 = 163 Then
          --双字节字符(常用全角字符)
          v_Retval := v_Retval || Chr(Code2 - 128);
          n_Loop   := n_Loop + 2;
        Elsif Code1 > 163 Then
          --汉字
          v_Retval := v_Retval || Cc;
          n_Loop   := n_Loop + 2;
        Elsif Code1 = 161 And Code2 = 161 Then
          --全角空格
          v_Retval := v_Retval || ' ';
          n_Loop   := n_Loop + 2;
        Else
          --其他双字节字符
          v_Retval := v_Retval || Cc;
          n_Loop   := n_Loop + 2;
        End If;
      End Loop;
    Return v_Retval;
    Exception
      When Others Then
        raise notice 'exception----%',sqlerrm;
        return;
  End;

select Trimall('住'宅类档案,中.获取;?') from dual;   
        trimall        
-----------------------
 住'宅类档案,中.获取;?
(1 row)

注意:在数据库有kdb_orafce扩展插件时

  • 删除插件 drop extension kdb_orafce。
  • 不能删除 kdb_orafce扩展插件时通过指定sys.substrb函数解决。
  • 不能删除 kdb_orafce扩展插件时通过encode函数可以避免,但是使用此函数会导致ascii值不正确。
  • 结合使用utl_raw程序包处理。需要安装create extension kdb_raw扩展插件。

五、关于ASCII码

ASCII简介

ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符。标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号, 以及在美式英语中使用的特殊控制字符。

其中:

0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符)如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;

ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响。
32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。

65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。

同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。

后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。

ASCII产生

在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了所谓的ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。

美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。

ASCII码算法

A在ASCII中定义为01000001,也就是十进制65,有了这个标准后,当我们输入A时,计算机就可以通过ASCII码知道输入的字符的二进制编码是01000001。而没有这样的标准,我们就必须自己想办法告诉计算机我们输入了一个A;没有这样的标准,我们在别的机器上就需要重新编码以告诉计算机我们要输入A。ASCII码指的不是十进制,是二进制。只是用十进制表示习惯一点罢了,比如在ascii码中,A的二进制编码为01000001,如果用十进制表示是65,用十六进制表示就是41H。

在ASCII码表中,只包括了一些字符、数字、标点符号的信息表示,这主要是因为计算机是美国发明的,在英文下面,我们使用ASCII表示就足够了!但是在汉字输入下面,用ASCII码就不能表示了,而汉字只是中国的通用表示,所以如果我们要在计算机中输入汉字,就必须有一个像ascii码的标准来表示每一个汉字,这就是中国的汉字国标码,它定义了汉字在计算机中的一个表示标准。通过这个标准,但我们输入汉字的时候,我们的输入码就转换为区位码,通过唯一的区位码得到这个汉字的字形码并显示出来。

汉字编码

0-127 是 7位ASCII 码的范围,是国际标准。

至于汉字,不同的字符集用的ascii 码的范围也不一样,常用的汉字字符集有GB2312-80,GBK,Big5,unicode 等。下面我重点说一说最常用的GB_2312 的字符集。

GB_2312 字符集是目前最常用的汉字编码标准,windows 95/98/2000 中使用的 GBK字符集 就包含了GB2312,或者说和GB2312 兼容,GB_2312 字符集包含了 6763个的 简体汉字,和682 个标准中文符号。在这个标准中,每个汉字用2个字节来表示,每个字节的ascii码为 161-254 (16 进制A1 - FE),第一个字节 对应于 区码的1-94 区,第二个字节 对应于位码的1-94 位。

161-254 其实很好记忆,在英文字符中,可打印的字符范围为33-126。将这对数加上128(或者说最高位置1),就可以得到汉字使用的字符的范围。

ASCII码大致可以分三部分

1.ASCII不可打印控制字符

ASCII表上的数字0–31分配给了控制字符,用于控制像打印机等一些外围设备。例如,12代表换页/新页功能。此命令指示打印机跳到下一页的开头。(参详ASCII码表中0-31、127)

ASCII code (Decimal)ASCII code (Binary)ASCII code (Octal)ASCII code (Hex)CharDescription
00000NULLNull character
01111SOHStart of Header
021022STXStart of Text
031133ETXEnd of Text, hearts card suit
0410044EOTEnd of Transmission, diamonds card suit
0510155ENQEnquiry, clubs card suit
0611066ACKAcknowledgement, spade card suit
0711177BELBell
081000108BSBackspace
091001119HTHorizontal Tab
10101012aLFLine feed
11101113bVTVertical Tab, male symbol, symbol for Mars
12110014cFFForm feed, female symbol, symbol for Venus
13110115dCRCarriage return
14111016eSOShift Out
15111117fSIShift In
16100002010DLEData link escape
17100012111DC1Device control 1
18100102212DC2Device control 2
19100112313DC3Device control 3
20101002414DC4Device control 4
21101012515NAKNAK Negative-acknowledge
22101102616SYNSynchronous idle
23101112717ETBEnd of trans. block
24110003018CANCancel
25110013119EMEnd of medium
2611010321aSUBSubstitute
2711011331bESCEscape
2811100341cFSFile separator
2911101351dGSGroup separator
3011110361eRSRecord separator
3111111371fUSUnit separator
12711111111777fDELDelete
2.ASCII可打印字符

数字 32–126 分配给了能在键盘上找到的字符,当您查看或打印文档时就会出现。数字127代表 DELETE 命令。

ASCII code (Decimal)ASCII code (Binary)ASCII code (Octal)ASCII code (Hex)CharDescription
321000004020spaceSpace
331000014121!Exclamation mark
341000104222"Double quotes ; Quotation mark ; speech marks
351000114323#Number sign
361001004424$Dollar sign
371001014525%Percent sign
381001104626&Ampersand
391001114727'Single quote or Apostrophe
401010005028(round brackets or parentheses, opening round bracket
411010015129)parentheses or round brackets, closing parentheses
42101010522a*Asterisk
43101011532b+Plus sign
44101100542c,Comma
45101101552d-Hyphen, minus sign
46101110562e.Dot, full stop
47101111572f/Slash, forward slash, fraction bar, division slash
4811000060300number zero
4911000161311number one
5011001062322number two
5111001163333number three
5211010064344number four
5311010165355number five
5411011066366number six
5511011167377number seven
5611100070388number eight
5711100171399number nine
58111010723a:Colon
59111011733b;Semicolon
60111100743c<Less-than sign
61111101753d=Equals sign
62111110763e>Greater-than sign ; Inequality
63111111773f?Question mark
64100000010040@At sign
65100000110141ACapital letter A
66100001010242BCapital letter B
67100001110343CCapital letter C
68100010010444DCapital letter D
69100010110545ECapital letter E
70100011010646FCapital letter F
71100011110747GCapital letter G
72100100011048HCapital letter H
73100100111149ICapital letter I
7410010101124aJCapital letter J
7510010111134bKCapital letter K
7610011001144cLCapital letter L
7710011011154dMCapital letter M
7810011101164eNCapital letter N
7910011111174fOCapital letter O
80101000012050PCapital letter P
81101000112151QCapital letter Q
82101001012252RCapital letter R
83101001112353SCapital letter S
84101010012454TCapital letter T
85101010112555UCapital letter U
86101011012656VCapital letter V
87101011112757WCapital letter W
88101100013058XCapital letter X
89101100113159YCapital letter Y
9010110101325aZCapital letter Z
9110110111335b[square brackets or box brackets, opening bracket
9210111001345c\Backslash, reverse slash
9310111011355d]box brackets or square brackets, closing bracket
9410111101365e^Circumflex accent or Caret
9510111111375f_underscore, understrike, underbar or low line
96110000014060`Grave accent
97110000114161aLowercase letter a, minuscule a
98110001014262bLowercase letter b, minuscule b
99110001114363cLowercase letter c, minuscule c
100110010014464dLowercase letter d, minuscule d
101110010114565eLowercase letter e, minuscule e
102110011014666fLowercase letter f, minuscule f
103110011114767gLowercase letter g, minuscule g
104110100015068hLowercase letter h, minuscule h
105110100115169iLowercase letter i, minuscule i
10611010101526ajLowercase letter j, minuscule j
10711010111536bkLowercase letter k, minuscule k
10811011001546clLowercase letter l, minuscule l
10911011011556dmLowercase letter m, minuscule m
11011011101566enLowercase letter n, minuscule n
11111011111576foLowercase letter o, minuscule o
112111000016070pLowercase letter p, minuscule p
113111000116171qLowercase letter q, minuscule q
114111001016272rLowercase letter r, minuscule r
115111001116373sLowercase letter s, minuscule s
116111010016474tLowercase letter t, minuscule t
117111010116575uLowercase letter u, minuscule u
118111011016676vLowercase letter v, minuscule v
119111011116777wLowercase letter w, minuscule w
120111100017078xLowercase letter x, minuscule x
121111100117179yLowercase letter y, minuscule y
12211110101727azLowercase letter z, minuscule z
12311110111737b{braces or curly brackets, opening braces
12411111001747c
12511111011757d}curly brackets or braces, closing curly brackets
12611111101767e~Tilde ; swung dash
3.扩展ASCII打印字符

扩展的ASCII字符满足了对更多字符的需求。扩展的ASCII包含ASCII中已有的128个字符,又增加了128个字符,总共是256个。即使有了这些更多的字符,许多语言还是包含无法压缩到256个字符中的符号。因此出现了一些ASCII的变体来囊括地区性字符和符号。例如,许多软件程序把ASCII表(又称作ISO8859-1)用于北美、西欧、澳大利亚和非洲的语言。

ASCII code (Decimal)ASCII code (Binary)ASCII code (Octal)ASCII code (Hex)CharDescription
1281000000020080ÇMajuscule C-cedilla
1291000000120181ületter u with umlaut or diaeresis, u-umlaut
1301000001020282életter e with acute accent or e-acute
1311000001120383âletter a with circumflex accent or a-circumflex
1321000010020484äletter a with umlaut or diaeresis, a-umlaut
1331000010120585àletter a with grave accent
1341000011020686åletter a with a ring
1351000011120787çMinuscule c-cedilla
1361000100021088êletter e with circumflex accent or e-circumflex
1371000100121189ëletter e with umlaut or diaeresis ; e-umlauts
138100010102128aèletter e with grave accent
139100010112138bïletter i with umlaut or diaeresis ; i-umlaut
140100011002148cîletter i with circumflex accent or i-circumflex
141100011012158dìletter i with grave accent
142100011102168eÄletter A with umlaut or diaeresis ; A-umlaut
143100011112178fÅCapital letter A with a ring
1441001000022090ÉCapital letter E with acute accent or E-acute
1451001000122191æLatin diphthong ae in lowercase
1461001001022292ÆLatin diphthong AE in uppercase
1471001001122393ôletter o with circumflex accent or o-circumflex
1481001010022494öletter o with umlaut or diaeresis ; o-umlaut
1491001010122595òletter o with grave accent
1501001011022696ûletter u with circumflex accent or u-circumflex
1511001011122797ùletter u with grave accent
1521001100023098ÿLowercase letter y with diaeresis
1531001100123199ÖLetter O with umlaut or diaeresis ; O-umlaut
154100110102329aÜLetter U with umlaut or diaeresis ; U-umlaut
155100110112339bøLowercase slashed zero or empty set
156100111002349c£Pound sign ; symbol for the pound sterling
157100111012359dØUppercase slashed zero or empty set
158100111102369e×Multiplication sign
159100111112379fƒFunction sign ; f with hook sign ; florin sign
16010100000240a0áLowercase letter a with acute accent or a-acute
16110100001241a1íLowercase letter i with acute accent or i-acute
16210100010242a2óLowercase letter o with acute accent or o-acute
16310100011243a3úLowercase letter u with acute accent or u-acute
16410100100244a4ñeñe, enie, spanish letter enye, lowercase n with tilde
16510100101245a5ÑSpanish letter enye, uppercase N with tilde, EÑE, enie
16610100110246a6ªfeminine ordinal indicator
16710100111247a7ºmasculine ordinal indicator
16810101000250a8¿Inverted question marks
16910101001251a9®Registered trademark symbol
17010101010252aa¬Logical negation symbol
17110101011253ab½One half
17210101100254ac¼Quarter, one fourth
17310101101255ad¡Inverted exclamation marks
17410101110256ae«Angle quotes, guillemets, right-pointing quotation mark
17510101111257af»Guillemets, angle quotes, left-pointing quotation marks
17610110000260b0Graphic character, low density dotted
17710110001261b1Graphic character, medium density dotted
17810110010262b2Graphic character, high density dotted
17910110011263b3Box drawing character single vertical line
18010110100264b4Box drawing character single vertical and left line
18110110101265b5ÁCapital letter A with acute accent or A-acute
18210110110266b6ÂLetter A with circumflex accent or A-circumflex
18310110111267b7ÀLetter A with grave accent
18410111000270b8©Copyright symbol
18510111001271b9Box drawing character double line vertical and left
18610111010272baBox drawing character double vertical line
18710111011273bbBox drawing character double line upper right corner
18810111100274bcBox drawing character double line lower right corner
18910111101275bd¢Cent symbol
19010111110276be¥YEN and YUAN sign
19110111111277bfBox drawing character single line upper right corner
19211000000300c0Box drawing character single line lower left corner
19311000001301c1Box drawing character single line horizontal and up
19411000010302c2Box drawing character single line horizontal down
19511000011303c3Box drawing character single line vertical and right
19611000100304c4Box drawing character single horizontal line
19711000101305c5Box drawing character single line horizontal vertical
19811000110306c6ãLowercase letter a with tilde or a-tilde
19911000111307c7ÃCapital letter A with tilde or A-tilde
20011001000310c8Box drawing character double line lower left corner
20111001001311c9Box drawing character double line upper left corner
20211001010312caBox drawing character double line horizontal and up
20311001011313cbBox drawing character double line horizontal down
20411001100314ccBox drawing character double line vertical and right
20511001101315cdBox drawing character double horizontal line
20611001110316ceBox drawing character double line horizontal vertical
20711001111317cf¤Generic currency sign
20811010000320d0ðLowercase letter eth
20911010001321d1ÐCapital letter Eth
21011010010322d2ÊLetter E with circumflex accent or E-circumflex
21111010011323d3ËLetter E with umlaut or diaeresis, E-umlaut
21211010100324d4ÈCapital letter E with grave accent
21311010101325d5ıLowercase dot less i
21411010110326d6ÍCapital letter I with acute accent or I-acute
21511010111327d7ÎLetter I with circumflex accent or I-circumflex
21611011000330d8ÏLetter I with umlaut or diaeresis ; I-umlaut
21711011001331d9Box drawing character single line lower right corner
21811011010332daBox drawing character single line upper left corner
21911011011333dbBlock, graphic character
22011011100334dcBottom half block
22111011101335dd¦Vertical broken bar
22211011110336deÌCapital letter I with grave accent
22311011111337dfTop half block
22411100000340e0ÓCapital letter O with acute accent or O-acute
22511100001341e1ßLetter Eszett ; scharfes S or sharp S
22611100010342e2ÔLetter O with circumflex accent or O-circumflex
22711100011343e3ÒCapital letter O with grave accent
22811100100344e4õLowercase letter o with tilde or o-tilde
22911100101345e5ÕCapital letter O with tilde or O-tilde
23011100110346e6µLowercase letter Mu ; micro sign or micron
23111100111347e7þLowercase letter Thorn
23211101000350e8ÞCapital letter Thorn
23311101001351e9ÚCapital letter U with acute accent or U-acute
23411101010352eaÛLetter U with circumflex accent or U-circumflex
23511101011353ebÙCapital letter U with grave accent
23611101100354ecýLowercase letter y with acute accent
23711101101355edÝCapital letter Y with acute accent
23811101110356ee¯Macron symbol
23911101111357ef´Acute accent
24011110000360f0Congruence relation symbol
24111110001361f1±Plus-minus sign
24211110010362f2underline or underscore
24311110011363f3¾three quarters, three-fourths
24411110100364f4Paragraph sign or pilcrow ; end paragraph mark
24511110101365f5§Section sign
24611110110366f6÷The division sign ; Obelus
24711110111367f7¸cedilla
24811111000370f8°Degree symbol
24911111001371f9¨Diaresis
25011111010372fa·Interpunct or space dot
25111111011373fb¹Superscript one, exponent 1, first power
25211111100374fc³Superscript three, exponent 3, cube, third power
25311111101375fd²Superscript two, exponent 2, square, second power
25411111110376feblack square
25511111111377ffnbspNon-breaking space or no-break space
更多信息,参见https://help.kingbase.com.cn/v8/index.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值