web-dev-qa-db-ja.com

NVARCHAR2列の精度は、descコマンドで表示されるよりも1.5倍低い

_nvarchar2_列の精度を更新したかったので、興味深いケースに遭遇しました。以下でそれを複製しようとしました:

_create table test_table1
 (col1 nvarchar2(100));

table TEST_TABLE1 created.

desc test_table1
Name Null Type           
---- ---- -------------- 
COL1      NVARCHAR2(150) 
_

nvarchar2列の表示精度は、指定された精度の1.5倍であることがわかりました。したがって、NVARCHAR2(375)型の列の精度を複製する必要がある場合は、NVARCHAR2(250)として宣言する必要があります。

説明を探してみましたが、見つかりませんでした。誰かこれについて何か考えがありますか? Oracle SQL Developerに接続するOracle-11gを使用しています。

NLS_SESSION_PARAMETERS

_select * from NLS_SESSION_PARAMETERS;

+-------------------------+------------------------------+
|        PARAMETER        |            VALUE             |
+-------------------------+------------------------------+
| NLS_LANGUAGE            | AMERICAN                     |
| NLS_TERRITORY           | AMERICA                      |
| NLS_CURRENCY            | $                            |
| NLS_ISO_CURRENCY        | AMERICA                      |
| NLS_NUMERIC_CHARACTERS  | .,                           |
| NLS_CALENDAR            | GREGORIAN                    |
| NLS_DATE_FORMAT         | YYYY.MM.DD HH24:MI:SS        |
| NLS_DATE_LANGUAGE       | AMERICAN                     |
| NLS_SORT                | BINARY                       |
| NLS_TIME_FORMAT         | HH.MI.SSXFF AM               |
| NLS_TIMESTAMP_FORMAT    | DD-MON-RR HH.MI.SSXFF AM     |
| NLS_TIME_TZ_FORMAT      | HH.MI.SSXFF AM TZR           |
| NLS_TIMESTAMP_TZ_FORMAT | DD-MON-RR HH.MI.SSXFF AM TZR |
| NLS_DUAL_CURRENCY       | $                            |
| NLS_COMP                | BINARY                       |
| NLS_LENGTH_SEMANTICS    | BYTE                         |
| NLS_NCHAR_CONV_EXCP     | FALSE                        |
+-------------------------+------------------------------+
_

NLS_DATABASE_PARAMETERS

_select * from NLS_DATABASE_PARAMETERS;
+-------------------------+----------------------------+
|        PARAMETER        |           VALUE            |
+-------------------------+----------------------------+
| NLS_LANGUAGE            | AMERICAN                   |
| NLS_TERRITORY           | SWITZERLAND                |
| NLS_CURRENCY            | SFr.                       |
| NLS_ISO_CURRENCY        | SWITZERLAND                |
| NLS_NUMERIC_CHARACTERS  | .'                         |
| NLS_CHARACTERSET        | AL32UTF8                   |
| NLS_CALENDAR            | GREGORIAN                  |
| NLS_DATE_FORMAT         | DD.MM.RR                   |
| NLS_DATE_LANGUAGE       | AMERICAN                   |
| NLS_SORT                | BINARY                     |
| NLS_TIME_FORMAT         | HH24:MI:SSXFF              |
| NLS_TIMESTAMP_FORMAT    | DD.MM.RR HH24:MI:SSXFF     |
| NLS_TIME_TZ_FORMAT      | HH24:MI:SSXFF TZR          |
| NLS_TIMESTAMP_TZ_FORMAT | DD.MM.RR HH24:MI:SSXFF TZR |
| NLS_DUAL_CURRENCY       | SF                         |
| NLS_COMP                | BINARY                     |
| NLS_LENGTH_SEMANTICS    | BYTE                       |
| NLS_NCHAR_CONV_EXCP     | FALSE                      |
| NLS_NCHAR_CHARACTERSET  | UTF8                       |
| NLS_RDBMS_VERSION       | 11.2.0.4.0                 |
+-------------------------+----------------------------+
_

nls_length_semantics

_show parameter nls_length_semantics;
Show parameters query failed 
_

解決

頑張ってくれてありがとう。問題は確かに_SQL Developer_にあります。

Unixで手動で接続してから実行してみました。正しい結果を得た

_create table test_table1
 (col1 nvarchar2(100));

Table created.

desc test_table1;
 Name  Null?   Type
 ---------------------------
 COL1          NVARCHAR2(100)
_

両方の回答をありがとう。賞金を宣言してくれてありがとう Paul と時間を割いて手伝ってくれてありがとう jsapkotaGiova .

6
Utsav

これはSQL Developerの問題であると確信しています...発行後、テーブルの記述を再試行してください。

alter session set NLS_LENGTH_SEMANTICS='CHAR';

今は正しいですか?そうでない場合は、Oracleリスナーをバイパスして、データベースサーバーでsqlplusを使用してテーブルを記述しようとします。

>export NLS_LANG=AMERICAN_SWITZERLAND.AL32UTF8 
>export Oracle_SID=<YOURINSTANCESID>
>sqlplus / as sysdba
>sqlplus>desc owner.table

結果が正しくない場合は、次を実行します。

SQLPLUS> alter session set NLS_LENGTH_SEMANTICS = 'CHAR'; SQLPLUS> desc owner.table

サーバーでそれができない場合は、sqldeveloperで同じことを試してください(ただし、リスナーはバイパスしません)。

>set NLS_LANG=AMERICAN_SWITZERLAND.AL32UTF8 
>C:\Oracle\client\product\12.1.0\client\sqldeveloper\sqldeveloper\bin\sqldevelope‌​rW.exe

変更 sqldevelope‌​rW.exe 道。 nvarchar2フィールドを宣言するとき、サイズは常にcharで表されます。 descコマンドを使用すると、サイズがバイト単位で表示されます。 Sqldeveloperは、何らかの方法でcharでvlaueを表示できません。また、sqldevleoperのバージョンを更新することもできます。

ジオバ

注:オフィシャルOracleのドキュメントは見つかりませんが、このwikiはSQL開発者のこの動作をよりよく説明しています。

NLSの長さの意味の設定

過去に、plsqldeveloperや他のクライアントでも同じ問題が見つかりました。たぶん、最新のバージョンは正しく動作します。

2
Giova

問題はNLS_NCHAR_CHARACTERSET = UTF8にあります。 NLS_NCHAR_CHARACTERSET = AL16UTF16を使用して、別のデータベースで同じテーブルをシミュレートしました。 describeステートメントは、テーブルの作成中に定義された正しい長さを示します。

UTF8は、1、2、3、または6バイト/文字にすることができます。4バイトのAL32UTF8文字は、UTF8では2倍3バイトとして格納されます。 1バイト文字をUTF8で格納する場合、1.5バイト(1 * 1.5 = 1.5)かかります。

詳細については、以下を参照してください。

AL32UTF8/UTF8(Unicode)データベースの文字セットの意味[ID 788156.1]

4
JSapkota