小编典典

LENGTH命令的奇怪行为-ORACLE

sql

我在这里遇到了我无法理解的被感染的情况。我将要编写的有关功能的文档也没有任何东西可以说明这一点。

我有一张桌子和一个田野titulovarchar2(55)。我在巴西,一些在这一领域中的字符有口音,我的目标是没有口音创建一个类似的字段(由原始字符代替,因为这成为a等等)。

我可以使用一堆函数像replacetranslate和其他函数那样来做,但是我在互联网上发现一个接缝看起来更加优雅,然后我使用了它。那就是问题所在。

我的更新代码是这样的:

update myTable 
   set TITULO_URL = replace(
                 utl_raw.cast_to_varchar2(
                           nlssort(titulo, 'nls_sort=binary_ai')
                                         )
                            ,' ','_');

就像我说的,目标是将每个重音符号转换成与之等效的形式,而没有重音加上空格 _

然后我得到了这个错误:

ORA-12899: value too large for column 
     "mySchem"."myTable"."TITULO_URL" (actual: 56, maximum: 55)

首先,尽管我也许这些功能正在添加一些字符,但让我检查一下。我执行了一条select命令,使我一行titulo包含55个字符。

select titulo from myTable where length(titulo) = 55

然后,我选择一行进行一些测试,我选择的行具有以下值:('FGHJT脫RYO DE YHJKS DA DGHQ脟脙A DE ASGA XCVBGLEASDE脭NASD'我确实对其进行了更改以保留数据,但结果是相同的)

当我执行以下选择语句时,事情变得很奇怪:

select a, length(a), b, length(b)
  from ( select 'FGHJT脫RYO DE YHJKS DA DGHQ脟脙A DE ASGA XCVBGL EASDE脭NASD' a,
                replace(
                   utl_raw.cast_to_varchar2( 
                               nlssort('FGHJT脫RYO DE YHJKS DA DGHQ脟脙A DE ASGA XCVBGL EASDE脭NASD', 'nls_sort=binary_ai')
                                           )
                       ,' ','_') b
           from dual
       )

此sql的结果是(为了更好的可视化,我将这些值一一递减):

                     a                                       LENGTH(a)
FGHJT脫RYO DE YHJKS DA DGHQ脟脙A DE ASGA XCVBGL EASDE脭NASD        55     
                     b                                       LENGTH(b)
fghjtoryo_de_yhjks_da_dghqcaa_de_asga_xcvbgl_easdeonasd        56

比较上面两个字符串,大小没有区别:

FGHJT脫RYO DE YHJKS DA DGHQ脟脙A DE ASGA XCVBGL EASDE脭NASD
fghjtoryo_de_yhjks_da_dghqcaa_de_asga_xcvbgl_easdeonasd

我已经在Toad,PLSQL Developer和SQLPLUSW上测试了此查询,结果均相同。所以我的问题是, 这个LENGTH(b)= 56来自
哪里?我知道这可能与字符集有关,但我不知道为什么。我什至用trim命令测试过,结果是一样的。

我做过的另一项测试

  • substr(b, 1,55) 结果是与上面相同的文本
  • lenght(trim(b)) 结果是56
  • substr(b,56) 结果为空(无null,无空格,仅空)

由@Sebas建议:

  • LENGTHB(b) 结果是56
  • ASCII(substr(b,56))

那么,再说一次: 这个LENGTH(b)= 56来自 哪里?
,很长的帖子,并感谢那些来到这里的人(阅读所有内容)。对于那些仍然不阅读的人表示感谢:)

最好的祝福


阅读 179

收藏
2021-03-23

共1个答案

小编典典

‘nlssort’函数的文档没有声明输出字符串将是输入字符串的规范化,或者它们将具有相同的长度。该函数的目的是返回可用于对输入字符串进行排序的数据。

参见http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions113.htm#SQLRF51561

诱使您使用它来规范化您的字符串,因为 显然 它可以工作,但是您在这里赌博…

哎呀,它甚至可以产生 LENGTH(b)= 200 并且 仍然 在做它应该做的事情:)

2021-03-23