PLSQL:获取游标rowcount并根据count添加到数组

时间:2016-09-16 18:41:00

标签: oracle plsql cursor

我有一个游标,它根据文件名从表中获取记录(文件名从数组传递)。现在如果文件名在表格中出现多次,我需要将文件名添加到duparray这么多次。

例如,如果test2.txt存在2次且test3.txt存在3次,我需要将duparray作为     {的test2.txt,的test2.txt,test3.txt,test3.txt,test3.txt}

但是根据以下代码,duparray即将推出     {test2.txt,test3.txt,test3.txt}因为我有ROWCOUNT> 1支票。

如果不存在该检查,则表中单次出现的文件名也会被添加到其中。请告知我应该在哪里纠正它。

CURSOR duplicateData IS
   SELECT file_name from tablename where file_name=p_filearray(i)           
   dupRow duplicateData%rowtype;

程序内:

OPEN duplicateData ;
   loop
   fetch duplicateData INTO dupRow;
   EXIT WHEN duplicateData %NOTFOUND;
      IF duplicateData %ROWCOUNT >1
      THEN
      p_duparray.EXTEND;
      p_duparray(p_duparray.LAST):=dupRow.file_name;
      END IF;
   end loop;
CLOSE duplicateData ;

3 个答案:

答案 0 :(得分:2)

鲍勃的第一个数据库编程定律指出:

NEVER USE A LOOP TO DO A SELECT'S JOB

在这种情况下,您可以使用

DECLARE
  FILENAME_COL_TYPE AS TABLE OF TABLENAME.FILENAME%TYPE INDEX BY PLS_INTEGER;

  colFile_names  ROW_COL_TYPE;
BEGIN
  SELECT FILE_NAME
    BULK COLLECT INTO colFile_names
    FROM TABLENAME
    ORDER BY FILE_NAME;
END;

这并没有解决已经存在于集合中的所需文件名的问题,但可能是文件集的集合是从SELECT语句派生的,因此选择适当文件名的标准可以包含在上面。

循环很糟糕。没有LOOPS!决不! (什么,永远不会?)不,永远不会! (从不?)好吧,几乎没有......

: - )

答案 1 :(得分:0)

我建议收集到cursor file_name和出现次数(cnt

CURSOR duplicateData IS
select file_name,count(*) cnt from tablename where file_name=p_filearray(i)
group by file_name; 

dupRow duplicateData%rowtype;
i number:=0;

然后使用for loop填充array ...

OPEN duplicateData ;
   loop
   fetch duplicateData INTO dupRow;
   EXIT WHEN duplicateData %NOTFOUND;
for i in 1..dupRow.cnt loop
      p_duparray.EXTEND;
      p_duparray(p_duparray.LAST):=dupRow.file_name;
end loop;
CLOSE duplicateData ;

答案 2 :(得分:0)

也许我错过了一些东西,但由于IF duplicateData%ROWCOUNT > 1,你看起来好像没有为第一次循环迭代做任何事情,这就是你丢失第一个值的原因。

我会自动将open-fetch-exit-end-close循环重构为简单形式:

for r in (
    select file_name from tablename where file_name=p_filearray(i)           
)
loop
    p_duparray.extend;
    p_duparray(p_duparray.last) := r.file_name;
end loop;

虽然Bob Jarvis提到你甚至不需要一个循环来将光标结果提取到一个数组中,但只能bulk collect它。

根据数组的需要,可能会使其成为由文件名索引的计数的关联数组。也就是说,只存储每个文件名一次并保持每个文件的计数,以便filecounts('test3.txt') = 3,而不是存储test3.txt三次。