Pl /sql过程执行出错



我的存储过程定义为

create or replace procedure TEST(
     name  IN table1.col_name%type,
     price IN table1.col_price%type
)
is
begin
    update table1  t set t.name =name where t.price = price;
commit;
end TEST;  

我正在尝试执行

exec TEST(name => 'John', price => 1000);

然而,它给出无效的SQL错误。我错过了什么?

输入参数%type语句声明列名是col_namecol_price。但这不是您在存储过程(nameprice)中引用它们的方式。

在列名之后命名变量可能会发生不好的事情。AskTom建议使用有限的变量命名约定:

  • 本地变量以L_
  • 开头
  • 参数以P_
  • 开头
  • 全局包变量以G_
  • 开头

这个链接对PL/SQL命名约定进行了很好的讨论。我个人只对大多数变量使用V_(除了索引和其他明显的东西),但这只是我。

最后,列名称中的col_似乎是多余的;仅使用nameprice作为列名。

所以,这就是说,我认为这是你想要的:

create table table1 (
    name    varchar2(30),
    price   number
);
create or replace procedure TEST(
     p_name  IN table1.name%type,
     p_price IN table1.price%type
)
is
begin
    update table1 
       set name = p_name 
     where price = p_price;
    commit;
end TEST;
/
insert into table1 values ('John', 500);
commit;
select * from table1;
exec TEST(p_name => 'Bob', p_price => 500);
select * from table1;
-- Clean up test artifacts
drop procedure test;
drop table table1;

给出输出:

table TABLE1 created.
PROCEDURE TEST compiled
1 rows inserted.
committed.
NAME                                PRICE
------------------------------ ----------
John                                  500 
anonymous block completed
NAME                                PRICE
------------------------------ ----------
Bob                                   500 
procedure TEST dropped.
table TABLE1 dropped.

我真的不明白变量前缀的方法。Oracle没有使用他们自己的API,如果他们这样做,那将是非常令人恼火的。这似乎总是一个变通,而不是一个修复。

对我来说,解决方法是用过程名命名变量。它使参数名称保持"干净",并使您的代码100%防止捕获:

create or replace procedure TEST(
  name  IN table1.col_name%type,
  price IN table1.col_price%type)
is
begin
  update table1 t
  set    name    = test.name
  where  t.price = price;
commit;
end TEST; 

最新更新