繁体   English   中英

Oracle软件包或函数…处于无效状态

[英]Oracle Package or function … is in an invalid state

我坚持使用Oracle存储过程调用。 代码看起来很简单,但是我真的不知道如何使它工作。 这是我创建程序的代码

DELIMITER @@
CREATE OR REPLACE PROCEDURE updateAward(_total_amount in Number, _no_of_sales in Number, _agent in NUMBER, _id in NUMBER) AS
    BEGIN
      update Award set total_amount = _total_amount, no_of_sales = _no_of_sales, agent_id = _agent where ID = _id @@
      commit @@

因此,当我通过NetBean(这是我目前拥有的唯一工具)执行代码时,代码运行良好。 我也尝试运行compile语句

alter PROCEDURE updateAward compile;

然后使用

select *
  from user_errors
 where name = 'ORG_SPGETTYPE'

select返回空值,证明编译过程正常。 但是,当我触发程序时

call updateAward(1,1,1,1);

它返回错误

Package or function UPDATEAWARD is in an invalid state

和命令

SELECT object_name FROM user_objects WHERE status='INVALID';

返回过程的名称。 我怎么解决这个问题 ?

更新1:

如果我用

BEGIN
updateAward(1,1,1,1);
End;

我有错误

    Error code 6550, SQL state 65000: ORA-06550: line 2, column 20:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

   := . ( % ;

更新2:

我放置分隔符的原因是因为“;”出现错误 通过某些VPN连接到另一个网络时(仍然不确定原因)。 因此,我更新了代码,就像您的答案一样,但是后来有了End; 在该过程的最后,然后获取Invalid SQL statement1 如果我删除它并执行(通过Netbean),则过程创建成功。 但是,编译并检查user_errors ,它得到了

"PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:     ; "

首先,您的过程语法看起来错误。 不要使用 DELIMITER因为该语法特定于MySQL。 相反,请尝试以下类似的方法。

 
 
 
  
  CREATE OR REPLACE PROCEDURE updateAward(_total_amount in Number, _no_of_sales in Number, _agent in NUMBER, _id in NUMBER) AS BEGIN update Award set total_amount = _total_amount, no_of_sales = _no_of_sales, agent_id = _agent where ID = _id; commit; END;
 
  

首先,您的程序存在一些错误:

  1. 您没有正确使用分隔符。 应使用定界符终止整个过程,而不是每一行。

    NetBeans SQL窗口不太了解SQL,因此无法确定过程何时结束以及其他什么开始。 通常,它使用分号( ; )来告知一条语句何时结束而另一条语句何时开始,但是存储过程可以在其中包含分号,从而无法使用。 相反,我们将分隔符更改为其他内容,以便NetBeans SQL窗口一次性将整个存储过程发送到数据库。

  2. 变量名称不允许以下划线( _ )开头。 特别是, 此Oracle文档页面上的 “架构对象命名规则”列表中的规则5指出:

    未引用的标识符必须以数据库字符集中的字母字符开头。

    下划线不是字母字符。

我已经完成了您的过程,固定了定界符的使用,并在每个参数名称的前面添加了一个额外的p (“ p代表“ parameter”),然后得到了以下内容,它们在NetBeans中成功运行并创建了一个没有错误的过程:

delimiter $$
CREATE OR REPLACE PROCEDURE updateAward(p_total_amount in Number, p_no_of_sales in Number, p_agent in NUMBER, p_id in NUMBER) AS
    BEGIN
      update Award set total_amount = p_total_amount, no_of_sales = p_no_of_sales, agent_id = p_agent where ID = p_id;
      commit;
    END;
$$
delimiter ;

其次,你写

[...]然后,使用

 select * from user_errors where name = 'ORG_SPGETTYPE' 

select返回空值,证明编译过程正常。

不。 这证明过程ORG_SPGETTYPE中没有错误(或不存在具有该名称的过程)。 您的过程名为updateAward ,Oracle会将其大写为UPDATEAWARD 尝试

select *
  from user_errors
 where name = 'UPDATEAWARD';

代替。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM