1

質問の短いバージョン:VARCHAR(n) Oracleデータベースの列に文字列の文字を格納するのに必要なバイト数をカウントする方法はありますか?

長いバージョン:次のOracle SQLスクリプトは、3番目のステートメントで失敗します。VARCHAR(10)1列に10文字を挿入しようとします。ただし、これらの文字の1つは、アキュートアクセントのあるAです。

CREATE TABLE TESTTABLE (NAME VARCHAR(10) NULL);

INSERT INTO TESTTABLE (NAME) VALUES ('abcdefghij');
--1 rows inserted.

INSERT INTO TESTTABLE (NAME) VALUES ('ábcdefghij');
--ORA-12899: value too large for column "ACME"."TESTTABLE"."NAME" (actual: 11, maximum: 10)

私のC#アプリケーションは文字列をOracleデータベースに格納しますが、列タイプをに変更するだけでは機能しませんNVARCHAR2(10)。アプリケーションは、より大きな文字列を10文字の制限までトリミングすることが期待されているため、Oracleはその長さについて文句を言いません。しかし、String.Lengthベースのトリムは非常に単純な戦略です。つまり、 「ábcdefghij」を10個のCLR文字すべてで無傷のままにします。

ステートメントを発行する前に文字列を「ábcdefghi」にトリミングできるように、 「á」がデータベース行で2バイトかかることをどのように検出できますか?INSERT

編集:この質問は、バイト長に基づいてUTF8文字列を短縮するための最良の方法に似ています

4

4 に答える 4

5

Oracle関数length(string)は文字数をlengthb(string)返し、バイト数を返します。

于 2013-03-11T20:02:25.273 に答える
4

これは、Oracleで使用するように設定されているエンコーディングによって異なります。System.Text.Encoding文字列インスタンスは、などの対応するインスタンスを使用してバイト配列に変換しますSystem.Text.Encoding.UTF8。(「GetBytes」メソッドを探しています)

于 2013-03-11T19:52:13.630 に答える
4

デフォルトでは、VARCHAR2(10)10バイトのストレージが割り当てられます。これは、データベースの文字セットとデータに応じて、10文字に相当する場合と等しくない場合があります。ただし、常に10文字を格納するように列を宣言することはできます。

可変幅の文字セットを使用している場合、ほとんどの場合、文字長のセマンティクスを使用して列を宣言する必要がありますVARCHAR2(10 CHAR)。そうすれば、1バイトを超えるストレージを必要とする文字があるかどうかに関係なく、常に10文字を格納できます。

何らかの理由でバイト長セマンティクスを使用して列を宣言するのが難しい場合は、LENGTHBorVSIZE関数を使用して文字列の長さをバイト単位で返すことができます。

select lengthb('ábcdefghij'), vsize('ábcdefghij')
  from dual;

結果の両方の列に対して11を返します。

于 2013-03-11T20:23:18.317 に答える
1

次のように、文字列のバイト単位で長さを取得できます。

UTF8Encoding Encoding = new UTF8Encoding();
byte[] UTF8String = Encoding.GetBytes("ábcdefghij");
int StringLenght = UTF8String.Length

実際、あなたの例では、11を返します。

于 2013-03-11T19:57:44.750 に答える