卡在我的程序中 [ORACLE]

Stuck in my procedure [ORACLE]

我正在尝试对我的程序执行操作,但它对我不起作用。我想在 table 旁边显示文件名,但不重复文件名,我解释得更好。假设我有这个 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  |
    -----------------------------------

当我 运行 我的程序时,它应该显示如下内容:

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

我试过以下程序:

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

希望我解释得很好,谢谢你的帮助。

问题是你输入了文件,即使它是重复的。如果您按如下所述修改代码,您将很容易找到解决方案:

  1. 为文件名创建一个变量并在循环之前用空varchar初始化它

  2. 您应该检查变量是否与文件名具有相同的值,而不是键入文件名。如果没有,则键入该文件,否则不键入它

  3. 处理文件名并输入新文件名后,将文件名存储在变量中

如果您运行您的报表在 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
;

只有纯粹的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

您可以使用两个光标而不是一个:

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;