ORACLE存储过程的参数问题

关于存储过程中大家有很多人可能遇见过就是编译OK。但是却是错误的,不能执行。在PL/SQL Devleoper中可以看见这个过程带个红叉。所以把这个问题整理一下。做个记录

为了说明问题先创建一个表

create table abc
(
 userid char(4),
 username varchar2(20),
 userage number
);

然后给这个表建过程。看看出错原因是什么

create or replace procedure apro(userid in char(4),username in varchar(20),age in number)
as
begin
      insert into abc values(userid,username,age);
end apro;

这个问题错在什么地方?错在过程中的参数后面不能再带参数。意思就是过程后的参数不要指定精度范围。把userid in char(4),username in varchar(20),age in number中的精度去掉改成userid in char,username in varchar,age in number后就OK没问题了。

-----------------------------
add by leolin
正常写法如下:
create or replace procedure apro(userid in char,username in varchar,age in number)
as
begin
          insert into abc values(userid,username,age);
end apro;

----------------

再看下一个

create or replace procedure apro
as
begin
    select * from abc;--或者select count(*)from abc
end apro;

这个语句够简单,应该没错了吧?参数我都没有写。就一条简单语句。可是一样的问题出先。编译OK,但是运行出错。什么问题呢?这是Oracle与SQL server最明显的不同之一,在Oracle过程中,不能使用“select * from tb_name”的方式显示查询结果。这种操作是没意义的。你可以作的修改是查询结果插入某个表或者查询出一个字段给一个变量这些就可以了。

-----------------------------
add by leolin
如果要返回结果集,应该是这样写:
procedure p_wt(mycs out mytype)
is
begin
      open mycs for select * from t_BOOK;
      --ORACLE存储过程中不能用select * from table 的方法。如果要返回结果用游标返回。
     --这里的游标定义在包声明中: type MyType is ref cursor;

end p_wt;

表格结构:
create table SCOTT.T_BOOK
(
  TITLE VARCHAR2(30),
  ID    NUMBER not null
)

.net的调用方法
                OracleCommand cmd2 = new OracleCommand("pk_wt.p_wt", con);
                cmd2.CommandType = CommandType.StoredProcedure;
                OracleParameter p1 = new OracleParameter("mycs",OracleDbType.RefCursor);
                p1.Direction = ParameterDirection.Output;
                cmd2.Parameters.Add(p1);
                OracleDataAdapter da = new OracleDataAdapter(cmd2);
                DataSet ds = new DataSet();
                da.Fill(ds, "T_BOOK");
                DataTableReader reader = ds.CreateDataReader();
                while (reader.Read())
                {
                    Console.WriteLine("标题:" + reader.GetString(0) + "ID:" + reader.GetDecimal(1).ToString());
                }

----------------

 

其实这样的问题不容易察觉,出错的时候往往根据一般逻辑思考又查不到有什么错误。而比如不能带参数精度,和简单查询要注意不能用过程来显示查询结果。这其实是一个编写过程的常识问题,但往往我们开发人员不是专门的DBA,会遇见这种问题的时候束手无策。

-----------------------------
add by leolin
还有就是在ODP.NET编程中,注意参数的添加顺序。
详见:http://blog.csdn.net/leo2u/archive/2007/05/31/1632321.aspx
---------

来源:http://blog.matrix.org.cn/ricky414/entry/%E5%AD%98%E5%82%A8%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E5%8F%82%E6%95%B0%E5%B8%B8%E8%AF%86%E5%B0%8F%E9%97%AE%E9%A2%98

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值