1

我的存储过程定义为

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 错误。我在这里想念什么?

4

2 回答 2

2

您的输入参数%type语句声称列名是col_nameand col_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.
于 2013-05-21T23:10:49.210 回答
0

我真的不明白变量前缀方法。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; 

更多关于捕获的信息

于 2013-05-31T16:33:08.973 回答