从PL / SQL游标中获取ALL结果的任何SIMPLE方法?

时间:2014-11-20 17:58:53

标签: sql oracle plsql sqlplus plsqldeveloper

问题的第二部分:如何使用SQL * Plus执行相同的操作(获取所有结果,没有任何循环)。

我正在编写一些PL / SQL脚本来使用Jenkins测试数据完整性。

我有这样的剧本:

declare
temp_data       SOME_PACKAGE.someRefCurFunction; // type: CURSOR
DATA1              NUMBER;
DATA2              NUMBER;
DATA3              SOMETHING.SOMETHING_ELSE%TYPE;

begin
  cursor := SOME_PACKAGE.someFunction('some',parameters,here);
  LOOP
   FETCH cursor INTO DATA1,DATA2,DATA3;
   EXIT WHEN temp_data%NOTFOUND;
   dbms_output.put_line(DATA1||','||DATA2||','||DATA3);
  END LOOP;
end;

Relsults看起来像这样:

Something1,,Something2
Something3,Something4,Something5
Something6,Something7,Something8

有时结果为空,如第1行所示。无关紧要,应该是。

此脚本的目的很简单 - 从光标中获取所有内容,逗号分隔数据,并打印带有结果的行。

这里的例子很简单,但这只是一个例子。 "现实生活"软件包有时包含数百个变量,处理大量数据库表。

我需要它尽可能简单。

是否有任何方法可以从光标中获取一切,如果可能的话,逗号分隔单个结果,并将其发送到输出? Jenkins测试中的最终输出应该是一个文本文件,以便能够与其他结果区分开来。

提前致谢:)

2 个答案:

答案 0 :(得分:1)

如果你真的对SQL * Plus脚本开放,而不是PL / SQL块

SQL> set colsep ','
SQL> variable rc refcursor;
SQL> exec :rc := SOME_PACKAGE.someFunction('some',parameters,here);
SQL> print rc;

应执行该过程并从游标中获取所有数据。您可以使用spool命令将生成的CSV输出假脱机到文件。当然,您可能会遇到SQL * Plus因为线条大小或其他类似问题而无法以干净的格式显示数据的问题 - 这可能会迫使您添加一些额外的SQL * Plus格式化命令(即{ {1}},set linesize等。)

对我而言,一个SQL * Plus脚本在编写一些生成最初发布的PL / SQL脚本的动态SQL或者(如果你在12c上)编写一些脚本时,对我来说并不是很明显使用column <<column name>> format <<format>>从返回的游标中获取数据的代码。

答案 1 :(得分:0)

答案显而易见。您当前有一个函数,它返回一个光标本身,返回数百个数据集(只显示三个)字段。您想要一个包含逗号分隔值的字符串。因此,根据相同的查询更改函数或编写另一个函数。

package body SOME_PACKAGE
...
-- The current function
function someFunction ...
  returns ref_cursor ...
  -- create cursor based on:
  select f1, f2, f3 --> Three (or n) fields
  from ...
  where ...;
  return generated_cursor;
end function;

-- The new function
function someOtherFunction ...
  returns ref_cursor ...
  -- create cursor based on:
  select f1 || ',' || f2 || ',' || f3 as StringField --> one string field
  from ...
  where ...;
  return generated_cursor;
end function;
end package;

这并不是你要求的全部。它确实保存了声明变量(一个而不是几百个)来一次读取一行中的数据,但是你仍然一次读取一行,而不是在我读到你的问题时读取一行中的每一行。但如果这样的超级获取是可能的,那将需要大量的内存。有时候我们会做一些只需要大量内存的事情,而我们只是尽力而为。但是你的要求&#34;似乎只是开发人员方便的问题。那个,imnsho,在消耗资源的优先事项列表中占有一席之地。

开发一个以您想要的最终形式返回数据的游标在我看来是最好的选择。