昨天在学习oracle存储过程的时候,写了一个存储过程的demo,语句是这样的:
create or replace procedure raisesalary(pname in varchar2(20)) as psssal testdelete.testid%type; begin select testid into psssal from testdelete where testname=pname; update testdelete set testid=(testid+10000) where testname=pname; dbms_output.put_line('the original salary'||psssal||' after the raise'||(psssal+1000)); end; /
想法是通过表的varchar(20)类型字段找到number类型字段,然后更改number类型的字段。表结构如下:
create table testdelete ( testid number, testname varchar2(20) )
将存储过程调用,出现结果如下:
connected to: oracle database 11g enterprise edition release 11.2.0.1.0 - 64bit production with the partitioning, olap, data mining and real application testing options create or replace procedure raisesalary(pname in varchar2(20)) 2 as 3 psssal testdelete.testid%type; 4 begin 5 select testid into psssal from testdelete where testname=pname; update testdelete set testid=(testid+10000) where testname=pname; dbms_output.put_line('the original salary'||psssal||' after the raise'||(psssal+1000)); 8 end; 9 / warning: procedure created with compilation errors. set serveroutput on; begin raisesalary('name2091'); commit; end; sql> 2 3 4 5 / raisesalary('name2091'); * error at line 2: ora-06550: line 2, column 5: pls-00905: object test.raisesalary is invalid ora-06550: line 2, column 5: pl/sql: statement ignored sql>
出现错误 :该存储过程无效。
what?明明刚刚建立的存储过程啊。然后我就翻到上面创建完之后的一句话,warning: procedure created with compilation errors. 翻译过来应该是:创建的过程带有编译的错误。
也就是说创建存储过程有错误,那么ok,找找存储过程看看哪错了。
emmmm,回头看了半天,就这么几行,死活没看出到底哪出问题了,没办法,baidu,google。
后来在stackoverflow看到了这个,原文链接如下:
https://stackoverflow.com/questions/48497140/oracle-sql-stored-procedure-object-invalid
楼主在里面发现了这么一句话:
you can’t give a size or precision restriction for the data type of a formal parameter to a function or procedure, so number(10,0)
should just be number
;
也就是说,你不能给函数和存储过程的参数指定数据的大小或者精度。ok,回头看看我这个参数,懂了,varchar2(20)是明显的给参数的类型指定精度了。需要改成varchar2这种类型。
或者直接写 表名.字段%type 也是可以的(亲测) 。
更改完之后运行如下:
create or replace procedure raisesalary(pname in varchar) 2 as 3 psssal testdelete.testid%type; 4 begin 5 select testid into psssal from testdelete where testname=pname; update testdelete set testid=(testid+10000) where testname=pname; dbms_output.put_line('the original salary'||psssal||' after the raise'||(psssal+1000)); 8 end; 9 / procedure created. begin raisesalary('name2091'); 3 commit; 4 end; 5 / the original salary2091 after the raise3091 pl/sql procedure successfully completed. sql>
改完之后明确看到已经没有warning了,出现的是 procedure created.
运行成功!问题解决。