Oracle函数选择*来自查询不给出任何结果

时间:2017-11-16 06:49:30

标签: oracle plsql oracle11g

以下是我正在使用的功能定义:

CREATE OR REPLACE FUNCTION MA_FACTSET.totalCustomers
RETURN number as
    total INTEGER := 0;
    FID VARCHAR2(30) := 'NT33H0-S-US';
    stmt varchar2(1000);

BEGIN
    execute immediate 'TRUNCATE TABLE MovingAverage';
    execute immediate 'DROP TABLE MovingAverage';
    execute immediate 'CREATE GLOBAL TEMPORARY TABLE MovingAverage
    (ID INTEGER,
     PDATE DATE,
     PPRICE FLOAT,
     MA1 FLOAT) ON COMMIT PRESERVE ROWS';

    stmt := 'INSERT INTO  MovingAverage (ID,PDATE,PPRICE) SELECT 
    ROWNUM,"DATE",P_PRICE FROM FP_BASIC_BD WHERE FS_PERM_SEC_ID = ''NT33H0-S-US''';
    DBMS_OUTPUT.PUT_LINE(stmt);
    execute immediate stmt;
    dbms_output.put_line(SQL%ROWCOUNT);
    commit;

    execute immediate 'UPDATE  MovingAverage A SET MA1 =(SELECT AVG(PPRICE) 
    FROM MovingAverage WHERE ID>=A.ID-5 AND ID<A.ID )' ;
    dbms_output.put_line(SQL%ROWCOUNT);
    commit;

    execute immediate 'SELECT * FROM MovingAverage ORDER BY ID ASC';
    dbms_output.put_line(SQL%ROWCOUNT);
    commit;

    dbms_output.put_line(total);
    RETURN total;
END;
/  

我已经应用了一些检查以确定该功能是否正常运行,例如获取SQL%ROWCOUNT

以下是该函数的DBMS输出:

INSERT INTO  MovingAverage (ID,PDATE,PPRICE) SELECT ROWNUM,"DATE",P_PRICE     FROM FP_BASIC_BD WHERE FS_PERM_SEC_ID = 'NT33H0-S-US'
4114
4114
0
0

我想知道为什么rowcount&#34; SELECT * FROM MovingAverage ORDER BY ID ASC&#34;是0.如果有任何方法可以在数据网格中打印完整的表。我正在使用TOAD for Oracle。

2 个答案:

答案 0 :(得分:1)

我建议你在不需要的地方重写你的函数去除动态sqls。另外,如果你有DDL,DML不使用PL / SQL函数,而是使用过程。

对于select中的EXECUTE IMMEDIATE语句,如果您使用BULK COLLECT INTO

,则会有效
CREATE OR REPLACE FUNCTION totalCustomers
   RETURN NUMBER
AS
   total   INTEGER := 0;
   FID     VARCHAR2 (30) := 'NT33H0-S-US';
   stmt    VARCHAR2 (1000);

   TYPE mrectype IS TABLE OF MovingAverage%ROWTYPE;

   mrec    mrectype;
BEGIN
   EXECUTE IMMEDIATE 'TRUNCATE TABLE MovingAverage';

   EXECUTE IMMEDIATE 'DROP TABLE MovingAverage';

   EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE MovingAverage
(ID INTEGER,
 PDATE DATE,
 PPRICE FLOAT,
 MA1 FLOAT) ON COMMIT PRESERVE ROWS';

   stmt :=
      'INSERT INTO  MovingAverage (ID,PDATE,PPRICE) SELECT 
ROWNUM,"DATE",P_PRICE FROM FP_BASIC_BD WHERE FS_PERM_SEC_ID = ''NT33H0-S-US''';
   DBMS_OUTPUT.PUT_LINE (stmt);

   EXECUTE IMMEDIATE stmt;

   DBMS_OUTPUT.put_line (SQL%ROWCOUNT);
   COMMIT;

   EXECUTE IMMEDIATE 'UPDATE  MovingAverage A SET MA1 =(SELECT AVG(PPRICE) 
FROM MovingAverage WHERE ID>=A.ID-5 AND ID<A.ID )';

   DBMS_OUTPUT.put_line (SQL%ROWCOUNT);
   COMMIT;

   EXECUTE IMMEDIATE 'SELECT * FROM MovingAverage ORDER BY ID ASC'
      BULK COLLECT INTO mrec;

   DBMS_OUTPUT.put_line (SQL%ROWCOUNT);
   COMMIT;
   DBMS_OUTPUT.put_line (total);
   RETURN total;
END;
/

像这样调用此函数。

SET SERVEROUTPUT ON
DECLARE
x NUMBER;
BEGIN
x := totalCustomers;
END;
/

您无法在SQL select

中调用该函数

答案 1 :(得分:1)

使用集合和表函数,函数可以返回可在SQL语句中查询的表。这在以下示例中进行了演示。

首先创建记录类型变量。

create or replace type t_record as object (i number,n varchar2(30));

创建基于记录类型变量的表类型变量。

create or replace type t_table as table of t_record;

然后我们可以按照以下步骤创建一个函数。

create or replace function return_table return t_table as
  v_ret   t_table;
begin

 --
 -- Call constructor to create the returned
 -- variable:
 --
v_ret  := t_table();

 --
 -- Add one record after another to the returned table.
 -- Note: the »table« must be extended before adding
 -- another record:
 --
    v_ret.extend; v_ret(v_ret.count) := t_record(1, 'one'  );
    v_ret.extend; v_ret(v_ret.count) := t_record(2, 'two'  );
    v_ret.extend; v_ret(v_ret.count) := t_record(3, 'three');

 --
 -- Return the record:
 --
    return v_ret;

end return_table;

有关详细信息和进一步扩展工作,请参阅以下网址。

https://renenyffenegger.ch/notes/development/databases/Oracle/PL-SQL/collection-types/return-table-from-function/index

<强> http://www.adp-gmbh.ch/ora/plsql/coll/return_table.html