11

私はここで、理解できない不慣れな状況に遭遇しました。また、これから書く関数のドキュメントにも、このことを明らかにするものはありません。

フィールドを持つテーブルがありますtitulo varchar2(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)

そして、最初は、これらの機能が何らかの特徴を追加しているのかもしれませんが、確認させてください。選択コマンドを実行して、titulo55 文字の行を取得しました。

select titulo from myTable where length(titulo) = 55

次に、いくつかのテストを行うために行を選択します。選択した行には次の値があります: 'FGHJTÓRYO DE YHJKS DA DGHQÇÃA DE ASGA XCVBGL EASDEÔNASD'(データを保持するためにビットを変更しましたが、結果は同じです)

次のselectステートメントを実行すると、物事が奇妙になりました:

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

2 つの文字列を上下に比較すると、サイズに違いはありません。

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 はどこから来たのでしょうか?

長い投稿で申し訳ありません。ここに来てくれた人たちに感謝します (すべてを読んでください)。とにかく読んでいない人に感謝します:)

よろしくお願いします

4

3 に答える 3

3

「nlssort」関数のドキュメントには、出力文字列が入力文字列の正規化であること、またはそれらが同じ長さになることは記載されていません。この関数の目的は、入力文字列の並べ替えに使用できるデータを返すことです。

http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions113.htm#SQLRF51561を参照してください。

どうやらそれが機能するので、文字列を正規化するためにそれを使用するのは魅力的ですが、ここでギャンブルをしています...

一体、それはLENGTH(b)=200を生成することさえありますが、それでも本来のことを実行しています :)

于 2013-11-07T20:47:42.040 に答える