文字列に余分なスペースが含まれていない場合は、trim()
それらを再度削除します。SQL*Plus は、予期しない方法で結果をフォーマットしているだけです。ドキュメントには、列の型のデフォルトの書式設定が記載されており、通常はシステム関数で解決できます (ただし、文字セットによって予想よりも大きくなる可能性があります)。
SQL*PlusとSQL Developer は、ケースの賢明なデフォルトを決定できないようですが、 . SQL*Plus は実際にはデータベースから結果セット カーソルを取得し、カーソル メタデータを使用して、表示用のフィールドに適用するデフォルトの幅を決定しているだけなので、そのメタデータから期待する長さを取得していません。しかし、どの長さを使用する必要がありますか?rpad
substr
データベースは、パディングの長さが単純な値である場合にのみ、値がどれだけ大きくrpad
なるかを認識します-ゼロでもかまいません(依存しているnullを返します)。パディングの長さが関数によって決定される場合、メタデータと実際のデータを返す前に結果セットのすべての値に対して計算する以外に、結果がどれくらい大きくなるかを知る方法はありません。これは実用的ではなく、データが変更されると、一貫性のない出力が生成されます。
あなたのケースでは表面的には簡単に見えますが、理論上の最大値を決定しようとすることも実用的ではありません。substr
元の値よりも長いものを返すことはできません。しかしrpad
、短い入力値からでも巨大なものを生成する可能性があるため、制限を (つまり、固定値から) 簡単に決定できない場合は、その可能性を考慮に入れる必要があります。
したがって、この動的 SQL が示すように、安全に動作し、 の最大長varchar2
(4000 文字)まで許可されます。
declare
l_curid integer;
l_desctab dbms_sql.desc_tab3;
l_colcnt integer;
begin
l_curid := dbms_sql.open_cursor;
dbms_sql.parse(l_curid, 'select rpad(ename, instr(ename,'' '')), '
|| 'rpad(ename, 4), '
|| 'substr(ename, 1, instr(ename,'' '')) '
|| 'from emp where ename like ''B%''' , dbms_sql.native);
dbms_sql.describe_columns3(l_curid, l_colcnt, l_desctab);
for i in 1 .. l_colcnt loop
dbms_output.put_line('column ' || i
|| ' ' || l_desctab(i).col_name
|| ' type ' || l_desctab(i).col_type
|| ' length ' || l_desctab(i).col_max_len
);
end loop;
dbms_sql.close_cursor(l_curid);
end;
/
column 1 RPAD(ENAME,INSTR(ENAME,'')) type 1 length 4000
column 2 RPAD(ENAME,4) type 1 length 16
column 3 SUBSTR(ENAME,1,INSTR(ENAME,'')) type 1 length 40
ご覧のとおり、固定長rpad
と aの長さはわかっていますがsubstr
(マルチバイト文字セットのため、サイズは実際の文字列の長さの 4 倍であることに注意してください)、rpad
関数を使用すると最大値に戻ります。
表示されているのは、SQL*Plus で 4000 文字の列が表示されていることです。SQL Developerでこれを行った場合、その列のヘッダーが実際に4000文字であることがわかります。SQL*Plus は、表示される列ヘッダーを行サイズに縮小し、次の列を別の行に折り返すことで少し役立ちます。