【问题标题】:Why won't this PL/SQL function compile?为什么这个 PL/SQL 函数不能编译?
【发布时间】:2019-12-08 01:29:05
【问题描述】:

我正在学习 Oracle Apex、Oracle SQL 和 PL/SQL,我目前正在学习函数。我编写了一个函数,其中创建了一个表,存储了数据并将表返回给调用查询。问题是代码无法编译。我看不出问题出在哪里,我已经将代码与包括该站点在内的各种在线资源进行了比较。在我看来一切都很好,所以答案对我来说并不明显。

这是我写的代码:

CREATE OR REPLACE TYPE t_table AS OBJECT
(
  futureValues NUMBER
);

CREATE OR REPLACE TYPE t_futureValues AS TABLE OF t_table;
/

CREATE OR REPLACE FUNCTION "CALCULATE_VALUE"( lastRowMinus0 IN NUMBER DEFAULT 1,
                                                   lastRowMinus1 IN NUMBER DEFAULT 2,
                                                   lastRowMinus2 IN NUMBER DEFAULT 3,
                                                   lastRowMinus3 IN NUMBER DEFAULT 4,
                                                   lastRowMinus4 IN NUMBER DEFAULT 5,
                                                   lastRowMinus5 IN NUMBER DEFAULT 6,
                                                   lastRowMinus6 IN NUMBER DEFAULT 7 )
RETURN t_futureValues AS 
                        tableObject         t_futureValues;
                        predictedValue      NUMBER := 0;
                        lastRowMinus0Value  NUMBER := 0;
                        lastRowMinus1Value  NUMBER := 0;
                        lastRowMinus2Value  NUMBER := 0;
                        lastRowMinus3Value  NUMBER := 0;
                        lastRowMinus4Value  NUMBER := 0;
                        lastRowMinus5Value  NUMBER := 0;
                        lastRowMinus6Value  NUMBER := 0;
                        avgDiff             NUMBER := 0;

BEGIN

        tableObject := t_futureValues();

        lastRowMinus0Value := 3;
        lastRowMinus1Value := 6;
        lastRowMinus2Value := 9;
        lastRowMinus3Value := 12;
        lastRowMinus4Value := 14;
        lastRowMinus5Value := 20;
        lastRowMinus6Value := 60;

        avgDiff := (lastRowMinus5Value - lastRowMinus6Value) + avgDiff;
        avgDiff := (lastRowMinus4Value - lastRowMinus5Value) + avgDiff;
        avgDiff := (lastRowMinus3Value - lastRowMinus4Value) + avgDiff;
        avgDiff := (lastRowMinus2Value - lastRowMinus3Value) + avgDiff;
        avgDiff := (lastRowMinus1Value - lastRowMinus2Value) + avgDiff;
        avgDiff := (lastRowMinus0Value - lastRowMinus1Value) + avgDiff;
        avgDiff := avgDiff / 6;                                            

        predictedValue := avgDiff + lastRowMinus0Value;                    

        begin
            for i in 2..13 loop
                predictedValue := predictedValue + avgDiff;

                IF predictedValue < 0 THEN
                   predictedValue := 0;
                END IF;

                insert into tableObject(futureValues)
                values(predictedValue);

            end loop;
        end;

        RETURN (tableObject);

END;

我得到的错误信息是:

ORA-06545:PL/SQL:编译错误 - 编译中止 ORA-06550:第 6 行,第 1 列:PLS-00103:遇到符号“CREATE” ORA-06550:第 0 行,第 0 列:PLS -00565: T_TABLE 必须作为潜在的 REF 目标(对象类型)完成

我毫不怀疑问题很简单,所以如果有人知道,我将不胜感激。

【问题讨论】:

  • 那么,第 6 行是声明 CREATE OR REPLACE TYPE t_futureValues AS TABLE OF t_table; 吗?请参阅docs.oracle.com/en/database/oracle/oracle-database/18/errmg/… abd 搜索 00565 了解全部原因,但了解全部原因超出了我在该领域的技能。
  • 尝试在CREATE OR REPLACE TYPE t_futureValues AS TABLE OF t_table 之前添加/
  • 第一个 CREATE TYPE 和第二个 CREATE TYPE 语句之间是否缺少斜线字符 /? (至少那是您发布的内容。)
  • 我之前曾尝试将斜杠放在那里,但这也给了我同样的错误信息。
  • 为了以后的读者,我终于把它编译了。我将每个“CREATE AND REPLACE”语句放在它们自己的脚本中并分别运行它们。然后我按照@BrianLeach 的建议修改了我的函数,将 INSERT INTO 语句替换为以下内容: tableobject.extend(); tableobject(tableobject.count).futureValues := predictValue; (这都是学习体验的一部分)。

标签: sql oracle function plsql


【解决方案1】:

我不经常使用类型,但您的插入尝试插入到数组中。表必须是插入的目标。

使用以下代码:

CREATE OR REPLACE TYPE brianl.t_table AS OBJECT
(
  futureValues NUMBER
);

CREATE OR REPLACE TYPE brianl.t_futureValues AS TABLE OF t_table;
/

CREATE OR REPLACE FUNCTION brianl."CALCULATE_VALUE"( lastRowMinus0 IN NUMBER DEFAULT 1,
                                                   lastRowMinus1 IN NUMBER DEFAULT 2,
                                                   lastRowMinus2 IN NUMBER DEFAULT 3,
                                                   lastRowMinus3 IN NUMBER DEFAULT 4,
                                                   lastRowMinus4 IN NUMBER DEFAULT 5,
                                                   lastRowMinus5 IN NUMBER DEFAULT 6,
                                                   lastRowMinus6 IN NUMBER DEFAULT 7 )
RETURN t_futureValues AS 
                        tableObject         t_futureValues;
                        predictedValue      NUMBER := 0;
                        lastRowMinus0Value  NUMBER := 0;
                        lastRowMinus1Value  NUMBER := 0;
                        lastRowMinus2Value  NUMBER := 0;
                        lastRowMinus3Value  NUMBER := 0;
                        lastRowMinus4Value  NUMBER := 0;
                        lastRowMinus5Value  NUMBER := 0;
                        lastRowMinus6Value  NUMBER := 0;
                        avgDiff             NUMBER := 0;

BEGIN

        tableObject := t_futureValues();

        lastRowMinus0Value := 3;
        lastRowMinus1Value := 6;
        lastRowMinus2Value := 9;
        lastRowMinus3Value := 12;
        lastRowMinus4Value := 14;
        lastRowMinus5Value := 20;
        lastRowMinus6Value := 60;

        avgDiff := (lastRowMinus5Value - lastRowMinus6Value) + avgDiff;
        avgDiff := (lastRowMinus4Value - lastRowMinus5Value) + avgDiff;
        avgDiff := (lastRowMinus3Value - lastRowMinus4Value) + avgDiff;
        avgDiff := (lastRowMinus2Value - lastRowMinus3Value) + avgDiff;
        avgDiff := (lastRowMinus1Value - lastRowMinus2Value) + avgDiff;
        avgDiff := (lastRowMinus0Value - lastRowMinus1Value) + avgDiff;
        avgDiff := avgDiff / 6;                                            

        predictedValue := avgDiff + lastRowMinus0Value;                    

        begin
            for i in 2..13 loop
                predictedValue := predictedValue + avgDiff;

                IF predictedValue < 0 THEN
                   predictedValue := 0;
                END IF;


                tableobject.extend();
                tableobject(tableobject.count).futureValues := predictedValue;
--                insert into tableObject(futureValues)
--                values(predictedValue);

            end loop;
        end;

        RETURN (tableObject);

END;

【讨论】:

  • 嗨。感谢您的答复。我按照您建议的方式更改了我的功能(当然没有'brianl'),但不幸的是我收到了相同的错误消息。
  • 谢谢布赖恩。您的建议以及分离脚本都奏效了。
猜你喜欢
  • 2016-07-30
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多