请教大家关于C#+Oracle的一些问题?
在Oracle的存储过程中如果要返回一个数据集(也就是一个Table)必须要用到游标,游标是不是必须在包里定义,能不能在一个系统中只定义一个游标,所有的存储过程要返回数据集都用这一个游标,但会不会产生两个以上用户同时要返回数据集时数据有误?还有请问大家在写Oracle存储过程时有什么经验没有?小弟第一次使用Oracle 问题点数:100、回复次数:27Top
1 楼xiaowangtian1117(笑望天1117)回复于 2005-08-02 13:29:34 得分 0
自己先顶一下Top
2 楼xiaowangtian1117(笑望天1117)回复于 2005-08-02 14:57:07 得分 0
请问怎样得到一个存储过程和包的输入输出参数属性?在SQL中是
select PARAMETER_NAME,PARAMETER_MODE,DATA_TYPE,NUMERIC_PRECISION,NUMERIC_SCALE,CHARACTER_MAXIMUM_LENGTH from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='" +ProcedureName+ "' order by ORDINAL_POSITIONTop
3 楼StarsRiver(学无止境)回复于 2005-08-02 15:56:19 得分 0
顶一下Top
4 楼dukejx(丢丢)回复于 2005-08-02 17:10:41 得分 0
为什么要用存储过程返回数据集?
存储过程怎么返回表?老大你没搞错吧???!!!
你要是想要一个表(包含其它表里的数据),你可以写一个视图(view),然后在.net里调用就可以了,你说的东东我不明白。Top
5 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 09:16:23 得分 0
我不想在程序里用SQL语句来进行对数据库操作。需要用存储过程对数据库操作Top
6 楼sos_zqx(踏破铁鞋)回复于 2005-08-03 09:33:13 得分 10
不要使用存储过程,请使用PRO*C的动态方法四,将所有SQL语句写在一个包里面。将程序设计成三层结构,中间层负责解释前台请求,调用动态SQL语句,返回结构集的工作
Top
7 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 10:40:56 得分 0
现在是项目经理要求用存储过程,用存储过程访问速度更快,系统维护更好。Top
8 楼kmblack(黑色)回复于 2005-08-03 11:20:17 得分 90
1.先定义程序包
Create or replace Package Pac_LanmuInfo
is
Type tabLanmu_01 is record(pacLanmuID number,packLanmuName varchar2(50),pacManagePath varchar2(200));
Type curLanmu_01 is ref cursor return tabLanmu_01;
end Pac_LanmuInfo;
2.创建存储过程
Create or replace Procedure pro_LanmuInfo_Sel
(inLanmuDeptID in number,cur out Pac_LanmuInfo.curLanmu_01)
is
begin
open cur for
Select LanmuID,LanmuName,ManagePath from T_Lanmu where (LanmuDeptID=inLanmuDeptID) and (LanmuID=HighLanmuID) ;
end;
3.在程序中调用存储过程
OracleConnection Conn=new OracleConnection("");
OracleCommand Cmd=new OracleCommand("pro_LanmuInfo_Sel",Conn);
OracleDataReader Dr;
Cmd.CommandType=CommandType.StoredProcedure;
Cmd.Parameters.Add("inLanmuDeptID",OracleType.Number);
Cmd.Parameters.Add("cur",OracleType.Cursor);
Cmd.Parameters["inLanmuDeptID"].Value=inDeptID;
Cmd.Parameters["cur"].Direction=ParameterDirection.Output;
Cmd.Connection.Open();
Dr=Cmd.ExecuteReader();
while(Dr.Read())
{
//输出和用SQL一样
}// end while
Dr.Close();
Cmd.Dispose();
Conn.Close();
Top
9 楼kmblack(黑色)回复于 2005-08-03 11:22:33 得分 0
MSDN:km_black@hotmail.com 如果有问题联系Top
10 楼kmblack(黑色)回复于 2005-08-03 11:28:47 得分 0
Oracle公司专门发布了一个.net组件包,性能比微软的Oracle组件要好,你可以到Oracle网站上找一下,网址记不清了,你自己去找一下吧.
Oracle各方面(表空间,表,索引等等)你都要做好,不然会很慢的,而且会死锁.Top
11 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 13:14:45 得分 0
请问怎样得到一个存储过程和包的输入输出参数属性?
CREATE OR REPLACE PROCEDURE "SCOTT"."PROC_TEST_CURSOR" (DDD OUT
HWTYPE.HWCURSOR)
as
begin
--这样可以动态设置游标了。
open DDD for SELECT DEPTNO,DNAME,LOC FROM DEPT;
end;
比如像上面的存储过程,我怎么得到这个存储过程的参数和他的属性
DDD OUT HWTYPE.HWCURSOR
Top
12 楼kmblack(黑色)回复于 2005-08-03 13:30:03 得分 0
一般都是这种写的,万一你改了表,程序包也不用改
Create or replace Package Pac_LanmuInfo
is
Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
Type curLanmu_01 is ref cursor return tabLanmu_01;
end Pac_LanmuInfo;
Top
13 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 14:28:15 得分 0
请问以下这句有什么意义?
Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
我看了在存储过程中没有用。
Top
14 楼kmblack(黑色)回复于 2005-08-03 14:58:34 得分 0
声明游标的类型
Type curLanmu_01 is ref cursor return tabLanmu_01;
存储过程中对应的是
cur out Pac_LanmuInfo.curLanmu_01Top
15 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 15:13:56 得分 0
但是Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
好像没有什么用处。
我看了一些文章,他们都在包中定义一些存储过程的参数,这需要吗?
如果在一个系统中只定义一个游标,那么在很多用户同时访问时会不会出现问题?
因为可能这个游标在一个存储过程中处于打开状况。Top
16 楼kmblack(黑色)回复于 2005-08-03 15:18:57 得分 0
1.包中定义一些存储过程的参数
Create or replace Package Pac_LanmuInfo
is
Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
Type curLanmu_01 is ref cursor return tabLanmu_01;
end Pac_LanmuInfo;
2.存储过程是独占的
3.在.net中存储过程里的游标就是不能关,关了就取不到数据了
你可以试一下,都是没问题的.
你在开发前最好插几十万条数据到表中,这样你做出来的程序就比较好了
Top
17 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 15:28:19 得分 0
我的意思是很多文章都定义一个包,在包中定义一个游标和一个存储过程,再在包体中写这个存储过程。但是你把包和存储过程分开来写,也就是只在包中定义一个游标,再在存储过程中引用这个游标,是这个意思吗?另外你在包中定义的
Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
有什么意义?谢谢!Top
18 楼kmblack(黑色)回复于 2005-08-03 15:34:08 得分 0
也可以在程序包中写,我这种写是为了方便管理啊,有些时候包头定义比较复杂,那包体更复杂,
Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
是定义数据类型,分别是T_Lanmu表中LanmuID列的类型,后面类推
存储过程中的游标
Select LanmuID,LanmuName,ManagePath from T_Lanmu where (LanmuDeptID=inLanmuDeptID) and (LanmuID=HighLanmuID) ;返回的类型和tabLanmu_01定义的是一样的啊,如果你改成
Select * from T_Lanmu where (LanmuDeptID=inLanmuDeptID) and (LanmuID=HighLanmuID)
会编译出错的,类型不符Top
19 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 15:36:12 得分 0
你是在包中定义了一个表结构
Type tabLanmu_01 is record(pacLanmuID T_Lanmu .LanmuID%Type,packLanmuName T_Lanmu .LanmuName%Type,pacManagePath T_Lanmu .ManagePath%Type);
用游标返回这个表结构,Type curLanmu_01 is ref cursor return tabLanmu_01;
但是我想在包中只定义一个游标在其他的存储过程中都应用这个游标可以吗?
因为我的存储过程很多,要返回很多select查询信息,如果针对每一个存储过程都要定义一个包会很麻烦,我不知道我的这种思路能不能实现。
例:
1.先定义程序包
Create or replace Package Pac_LanmuInfo
is
Type curLanmu_01 is ref cursor ;
end Pac_LanmuInfo;
2.创建存储过程
Create or replace Procedure pro_LanmuInfo_Sel
(inLanmuDeptID in number,cur out Pac_LanmuInfo.curLanmu_01)
is
begin
open cur for
Select LanmuID,LanmuName,ManagePath from T_Lanmu where (LanmuDeptID=inLanmuDeptID) and (LanmuID=HighLanmuID) ;
end;
Top
20 楼kmblack(黑色)回复于 2005-08-03 15:39:14 得分 0
不可以.Oracle就是比较麻烦一点,你这种编译肯定出错.Top
21 楼kmblack(黑色)回复于 2005-08-03 15:41:01 得分 0
Type curLanmu_01 is ref cursor ;没有定义类型
你可以自己试着搞一下.Top
22 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 15:51:15 得分 0
那如果像你所写的就是要为每一个要返回数据集的存储过程都要定义一个包,游标和要返回的数据类型是吗?那如果我要在select中要返回一列空值,或一个字符列怎么办?
例:Select LanmuID,LanmuName,ManagePath,'' as test,'qqq' as test1 from T_Lanmu where (LanmuDeptID=inLanmuDeptID) and (LanmuID=HighLanmuID) ;
Top
23 楼kmblack(黑色)回复于 2005-08-03 16:14:08 得分 0
都要在包头中定义游标类型,然后在存储过程中引用定义的类型Top
24 楼kmblack(黑色)回复于 2005-08-03 16:17:34 得分 0
看见了没,输出字段不一样,每次都要定义
Create or replace Package Pac_LanmuInfo
is
Type tabLanmu_01 is record(pacLanmuID number,packLanmuName varchar2(50),pacManagePath varchar2(200));
Type tabLanmu_02 is record(pacLanmuID number,packLanmuName varchar2(50));
Type curLanmu_02 is ref cursor return tabLanmu_02;
Type curLanmu_01 is ref cursor return tabLanmu_01;
end Pac_LanmuInfo;Top
25 楼xiaowangtian1117(笑望天1117)回复于 2005-08-03 17:14:58 得分 0
Create or replace Package PAC_CUR
is
Type tabconfig_data_01 is record(userlist_time number,userlist_open number);
Type curLanmu_01 is ref cursor return tabLanmu_01;
end PAC_CUR;
Create or replace Procedure select_cinfig_data
(
cur out PAC_CUR.curLanmu_01
)
is
begin
open cur for
Select USERLIST_TIME,USERLIST_OPEN from CONFIG_DATA ;
end select_cinfig_data;
不行有什么问题吗?Top
26 楼kmblack(黑色)回复于 2005-08-03 18:02:49 得分 0
要一步,一步的来
先创建程序包
然后再创建存储过程
错误是在什么地方?Top
27 楼xiaowangtian1117(笑望天1117)回复于 2005-08-04 10:51:06 得分 0
今天调试了一下,用你给的方法已经成功!谢谢!Top




