2017-01-29 2 views
1

手続き中に操作を実行しようとしていますが、それは私のためには機能しません。ファイルの名前を繰り返し表示せずに、テーブルの横にファイルの名前を表示したいと思います。私の手続きでスタックされている[ORACLE]

create or replace procedure files(p_user IN dba_segments.owner%type) 
is 
    cursor c_cursor is 
    select d.file_name, s.segment_name, s.segment_type 
    from dba_data_files d, dba_segments s 
    where segment_type = 'TABLE' 
    and s.owner=p_user; 

    v_cursor c_cursor%rowtype; 

begin 
for v_cursor in c_cursor loop 
    if v_cursor.segment_type='TABLE' then 
    dbms_output.put_line('File' || v_cursor.file_name); 
    dbms_output.put_line(' Table Nº:'' '|| v_cursor.segment_name); 
    end if; 
end loop; 
end files; 
/

しかし結果:私は、次の手順を試してみました

File: f1.dbf 
    Table1.1 
    Table1.2 
File: f2.dbf 
    Table2.1 
File: f3.dbf 
    Table3.1 
    Table3.2 

:私は私の手順を実行すると

----------------------------------- 
    |  file   | name_table| 
    | ----------------------------------| 
    | /home/peter/f1.dbf | table1.1 | 
    | /home/peter/f1.dbf | table1.2 | 
    | /home/peter/f2.dbf | table2.1 | 
    | /home/peter/f3.dbf | table3.1 | 
    | /home/peter/f3.dbf | table3.2 | 
    ----------------------------------- 

が、それはこのような何かを表示する必要がありますのは、私は、このテーブルがあるとしましょう私の手続きは以下の通りです:

File: /home/peter/f1.dbf 
    Table1.1 
File: /home/peter/f1.dbf 
    Table1.2 
File: /home/peter/f2.dbf 
    Table2.1 
File: /home/peter/f3.dbf 
    Table3.1 
File: /home/peter/f3.dbf 
    Table3.2 

私はよく説明し、助けてくれてありがとうと思います。

+0

を。 *常に*適切で明示的な 'JOIN'構文を使用します。 –

+0

@ GordonLinoffアドバイスをいただきありがとうございます。 – Randomuser1204281

+0

@ Randomuser1204281あなたはfile_nameでも注文する必要があります。 – BobC

答えて

0

あなたの代わりに1の2つのカーソルを使用することができます:* `FROM`句にカンマを使用しないでください*

CREATE OR REPLACE PROCEDURE FILES (P_USER IN DBA_SEGMENTS.OWNER%TYPE) 
IS 
    CURSOR C_FILE 
    IS 
     SELECT D.FILE_NAME 
      FROM DBA_DATA_FILES D, DBA_SEGMENTS S 
     WHERE SEGMENT_TYPE = 'TABLE' AND S.OWNER = P_USER 
     GROUP BY D.FILE_NAME; 

    CURSOR C_SEGMENT (
     P_FILE IN VARCHAR2) 
    IS 
     SELECT SEGMENT_NAME 
     FROM DBA_DATA_FILES D, DBA_SEGMENTS S 
     WHERE  SEGMENT_TYPE = 'TABLE' 
      AND S.OWNER = P_USER 
      AND D.FILE_NAME = P_FILE; 
BEGIN 
    FOR REC_FILE IN C_FILE 
    LOOP 
     DBMS_OUTPUT.PUT_LINE ('File' || REC_FILE.FILE_NAME); 

     FOR REC_SEG IN C_SEGMENT (REC_FILE.FILE_NAME) 
     LOOP 
     DBMS_OUTPUT.PUT_LINE (' Table Nº:'' ' || REC_SEG.SEGMENT_NAME); 
     END LOOP; 
    END LOOP; 
END FILES; 
1

問題は、繰り返してもファイルを入力することです。後述のように、コードを変更した場合、あなたは簡単に解決策に到達します:

  1. をファイル名に変数を作成し、ループ

  2. 前に空varcharでそれを初期化する代わりに、ファイル名を入力するのあなた変数がファイル名と同じ値を持つかどうかをチェックする必要があります。ない場合は、ファイルを入力し、それが新しかった場合は、ファイル名を取り扱い、入力した後、レポートを実行している場合は、それ以外の場合に

  3. を入力しないと、可変

0

でファイル名を保存しますSQLPlusでは、単にBREAKコマンドを使用することができます。

break on file_name 

select d.file_name, s.segment_name, s.segment_type 
    from dba_data_files d, dba_segments s 
    where segment_type = 'TABLE' 
    and s.owner=&p_user 
order by d.file_name 
; 
3

純粋なSQLでのみ目標を達成できます。

select s_file, s_name 
    from ( select d.file_name 
       , s.segment_name as s_name 
       , row_number() over(partition by file_name order by 1) rn 
       , case when grouping_id(segment_name) = 1 then 'File: ' || d.file_name end s_file 
       from dba_data_files d, dba_segments s 
      where segment_type = 'TABLE' and s.owner = user 
      group by file_name, rollup(segment_name)) 
order by file_name, rn desc 
関連する問題