3

clobOracle 10g のピボットを作成するために、データ型からデータをフェッチし、varchar2 に変換する必要があるという要件があります。

私は以下を使用しています

select max(case 
             when key='abc' 
             then dbms_lob.substr(value) 
           end) as data_abc 
  from table.

値が 4000 未満の場合、上記のクエリは正常に機能しますが、4000 を超える場合は、バッファ制限のエラーが表示されます。dbms_lob.substr()いくつかのブログを読んで、SQL では 4000 文字しか処理できないが、pl/sql ステートメントでは最大 32k を処理できることを知りました。

プロシージャを作成して実行すると、正常に動作します。しかし、私は関数でそれを使いたいです。以下は私の機能です:

create or replace FUNCTION CLOBTOVARCHAR 
RETURN varchar2 is out_attribute_var varchar2(32767) ;
BEGIN
  FOR i IN (select attribute_Value  from car_course_attribute where id=1547156)
  LOOP
    out_attribute_var := dbms_lob.substr(i.attribute_Value, 32000, 1);
  END LOOP;

  RETURN out_attribute_var;

EXCEPTION
  WHEN OTHERS THEN
    raise_application_error(-20001, 'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END CLOBTOVARCHAR;

データが小さい場合は問題なく動作しますが、データが 4k より大きい場合は同じエラーが返されます。今、私は2つの質問があります.1)clobピボットを取得したいので、をvarchar2に変換することで正しくやっていますか?2)関数は正しいですか?

4

2 に答える 2

2

残念ながら、Oracle の SQL は 4000 までの varchar をサポートしています
。あなたの関数は SQL クエリでは動作しません。
この制限を 32767 文字まで増やす oracle 12c にアップグレードできます。

ただし、11g で機能する簡単な回避策があります。3 列の CLOB ピボットの例を次に示します。

SELECT (select val from xx
        where rowid = a_rid ) a,
       (select val from xx
        where rowid = b_rid ) b,
       (select val from xx
        where rowid = c_rid ) c
from (
  select max( case key when 'A' then rowid end ) a_rid,
         max( case key when 'B' then rowid end ) b_rid,
         max( case key when 'C' then rowid end ) c_rid
  from xx
);

これは3 つの文字列を含むSQLFiddle デモで、それぞれに 7996 文字が含まれています。

このデモの結果行は非常に幅が広​​く、150 を超える「水平ページ」があります SQLFiddle が 24K 文字幅の行を表示できることに驚きました このデモの 3 番目のクエリは、ピボットされた列の長さを表示し、それぞれが 7996 文字です。

于 2013-08-19T17:31:32.857 に答える
1
dbms_lob.substr( clob_column, for_how_many_bytes, from_which_byte ); 

例えば:

select dbms_lob.substr( x, 4000, 1 ) from T; 

clob の最初の 4000 バイトを取得します。私が行ったように SQL を使用する場合、最大長は 4000 であることに注意してください。plsql を使用して 32k を取得できます。

declare 
my_var long; 
begin 
for x in ( select X from t ) 
loop 
my_var := dbms_lob.substr( x.X, 32000, 1 ); 

....

これは2016年くらいの時点で正確でした。Oracle Database 12c の時点で、拡張 varchars2 をサポートするようになりました (現在は最大 32k の長さです)。これは 32,000 未満で、マルチバイト文字セット (1 文字あたり 2、3、または 4 バイト) を使用している場合は文字を変更できます。

ここでトムが最初に答えた

ここでは、LiveSQL で SQL のみを使用して、8k の長い文字列を varchar2 に変換する作業シナリオがあります。

拡張 varchars が有効になっている 12c 環境のコード。

create table long_vars2 (a integer, xyz varchar2(8000), clobs clob);

create or replace procedure p( p_x in int, p_new_text in varchar2 )  
 as  
 begin  
 insert into long_vars2 (a, xyz, clobs) values ( p_x, p_new_text, p_new_text );  
 end;  
/

exec p(1, rpad('*',8000,'*') );

select dbms_lob.substr( clobs, 7000, 1 ) from long_vars2;
于 2018-03-17T13:22:45.537 に答える