-1

私の目的は、PL/SQL を使用して Oracle でスクリプトを記述し、以下の形式でデータベース テーブルからデータを取得することです。

table_name|table_size|avg_row_length

これは、データベースで使用可能なすべてのテーブルに必要です。以下は、特定のスキーマの上記の詳細を取得するために記述しようとしているスクリプトです。ただし、エラーを下回っています

PLS-00103 : 次のいずれかを想定しているときに、記号"AVG_ROW_SIZE"が見つかりました: := ; null ではないデフォルトのcharec

SET serveroutput on;
clear screen;

set lin 20000;
set trimspool on;
set feed off;
set verify off;
set head off;

spool &&1..metadata_report.out

DECLARE
    v_tbl_name   VARCHAR2(1500);
    v_row_num    NUMBER(20);
    table_size   NUMBER(20);
    avg_row_size NUMBER(30);
    CURSOR c1 IS
      SELECT DISTINCT table_name
      FROM   all_tables
      WHERE  owner = Upper('&&1')
      ORDER  BY table_name ASC;
    c1_rec       c1%ROWTYPE;
BEGIN
    OPEN c1;

    LOOP
        FETCH c1 INTO c1_rec;

        exit WHEN c1%NOTFOUND;

        EXECUTE IMMEDIATE
'select sum((bytes/1024)) from user_extents where segment_name = "'||c1_rec.table_name||'"' INTO
table_size;

EXECUTE IMMEDIATE
'select decode(count(*),NULL,0, count(*)) FROM &&1.."'||c1_rec.table_name||'"'
    INTO v_row_num;

IF( v_row_num = 0 ) THEN
  avg_row_size := 0;
ELSE
  EXECUTE IMMEDIATE 'SELECT table_size/v_row_num FROM DUAL' INTO avg_row_size;
END IF;

dbms_output.Put_line(c1_rec.table_name
                     ||'|'
                     ||table_size
                     ||'|'
                     ||avg_row_size);
END LOOP;

CLOSE c1;
END; 

/
4

3 に答える 3

2

エラーが発生し、スクリプトが表示されない場合、この情報を取得しようとしていDBA_TABLESて、列を使用したいのにAVG_ROW_LEN名前を間違って入力したと推測されAVG_ROW_SIZEます. 私の推測では、クエリを作成しようとしている

SELECT table_name, num_rows * avg_row_len, avg_row_len
  FROM dba_tables

ただし、データDBA_TABLESが正しくない可能性があることに注意してください。せいぜい、前回テーブルで統計が収集されたときのテーブルの状態の概算です。しかし、表で統計が収集されなかった可能性は十分にあります。または、テーブルのデータ量が非常に少なく、現在は数十億の行があるときに統計が収集されました。ただし、多くの状況では、統計がかなり正確であり、これらの概算値が十分に近いと想定するのが合理的です。もちろん、OWNER単一のデータベースに同じ名前の異なるテーブルが多数存在する可能性があるため、クエリに列を追加することをお勧めします。

また、定義につまずく可能性もあります。テーブルの「行の平均の長さ」または「テーブルのサイズ」は、人によって意味が大きく異なります。たとえば、テーブルに out-of-line が含まれている場合はどうなりますLOBか? はテーブルのセグメントに格納されていないLOBため、テーブルのサイズを計算するときにのサイズを数えますか? LOBテーブルに 100 万個の空のブロックを追加すると、行の平均長は変わりますか? テーブルのサイズを行数で割ったものとして定義したい場合はそうです。テーブルから 1 行のデータをフェッチした場合に返されるデータの平均量として定義する場合は、そうではありません。

さらに精度が必要な場合は、DBA_SEGMENTSテーブルを使用して、ディスク上のさまざまなセグメントのサイズを取得できます。ただし、定義によってはDBA_LOBS、テーブルのサイズの計算に含めるために、特定のテーブルに関連する LOB セグメントを特定するなど、他のデータ ディクショナリ テーブルを使用する必要がある場合があります。パッケージを使用してDBMS_SPACE、テーブル内の空きスペースの量に関する情報を取得できます。テーブル内の行数を正確にカウントしたい場合は、SELECT COUNT(*) FROM table_name非常にコストがかかる可能性がある を実行する必要があります。

于 2013-02-13T18:05:45.823 に答える
0

calc avg row len の例を次に示します。 http://www.dba-oracle.com/t_average_row_length.htm 残りを追加できます... PL/SQL は必要ありません。

于 2013-02-13T17:50:10.017 に答える