1

Oracle 11g を使用しています。Scott アカウントとデモEMPテーブルを使用しています。ENAMEBRUCE WILLIAMとのレコードを 1 枚挿入しました。私の目的は、名と姓を 2 つの列に表示することです。私はこのコードを使用しました:

select trim rpad(ename, instr(ename,' ')))   "First Name", 
       trim(substr(ename, instr(ename,' '))) "Last Name" 
  from emp;

これは奇妙な結果をもたらします。First Nameが 2 行目に拡張されます。使った

select trim(substr(ename, 1, instr(ename,' '))), 
       trim(substr(ename, instr(ename, ' '))) 
  from emp;

期待どおりの出力が得られました。私の質問は、クエリの最初の行が余分なスペースを与えているのはなぜですか?

4

2 に答える 2

1

文字列に余分なスペースが含まれていない場合は、trim()それらを再度削除します。SQL*Plus は、予期しない方法で結果をフォーマットしているだけです。ドキュメントには、列の型のデフォルトの書式設定が記載されており、通常はシステム関数で解決できます (ただし、文字セットによって予想よりも大きくなる可能性があります)。

SQL*PlusとSQL Developer は、ケースの賢明なデフォルトを決定できないようですが . SQL*Plus は実際にはデータベースから結果セット カーソルを取得し、カーソル メタデータを使用して、表示用のフィールドに適用するデフォルトの幅を決定しているだけなので、そのメタデータから期待する長さを取得していません。しかし、どの長さを使用する必要がありますか?rpadsubstr

データベースは、パディングの長さが単純な値である場合にのみ、値がどれだけ大きく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 は、表示される列ヘッダーを行サイズに縮小し、次の列を別の行に折り返すことで少し役立ちます。

于 2012-12-11T19:49:32.857 に答える
0
lpad ('string', n [, 'string_pad')
rpad ('string', n [, 'string_pad')

文字列はstring_padで長さnまでパディングされたままになります。string_padを省略すると、デフォルトのrpadと同様にスペースが使用されます が、パッドは左ではなく右になります。

http://www.adp-gmbh.ch/ora/sql/rpad.htmlから

そしてここに理解するための良い例があります

begin

  for i in 1 .. 15 loop
    dbms_output.put_line(
      rpad('string', i) || '<'
    );
  end loop;

end;
于 2012-11-30T09:01:58.010 に答える