Search code examples
sqloracle-databaseplsqlprocedureoracle12c

Stuck in my procedure [ORACLE]


I am trying to perform an operation on my procedure but it does not work for me. I want to show the name of a file next to the tables that it has but without repeating the name of the file, I explain better. Let's say I have this table:

    -----------------------------------
   |        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  |
    -----------------------------------

When I run my procedure it should show something like this:

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

I have tried the following procedure:

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;
/

But the result of my procedure is as follows:

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

I hope I explained well and thank you for the help.


Solution

  • you can use two cursors instead of one:

    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;