关于存储过程中大家有很多人可能遇见过就是编译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
---------