关于使用ADO组件调用oracle存储过程或者函数返回游标的问题

tianhxk 2008-07-24 10:44:15
我目前搞定的方式是用 Tadoquery/TAdoconnection可以调用oracle的过程或者函数返回游标
with AdoQry do begin
AdoQry.Connection := desconn;
Sql.Clear;
Sql.Add('{? = call sp_test_z(?,?)}');
Parameters.CreateParameter('p_RETURN',ftinteger, pdReturnvalue,4,0);
Parameters.CreateParameter('p_oc_date',ftinteger,pdInput,4,0);
Parameters.CreateParameter('p_oc1_date',ftinteger,pdInput,4,0);
Parameters.ParamByName('p_oc_date').value := 20080722;
Parameters.ParamByName('p_oc1_date').value := 20080724;
open;
DesDs.Recordset := AdoQry.recordset;
create or replace function sp_test_z
(
p_oc1_date Hstype.Hsint,
p_oc_date Hstype.Hsint,
p_cursor out Hstype.T_CURSOR
)
return number
is
begin
open p_cursor for select exch_date from conexchangedate
where exch_date = P_oc_date;
return 0;
end;
/
这样可以读取到游标返回的数据!但是这里有些问题,传入参数必须按照函数定义的参数顺序传参,这是很不方便的地方,并且所有的参数都需要create一把,像sql server里,可以直接这么
用 exec sp_test_z @oc_date = 20080722,@oc1_date = 20080724就可以了!而不是每个参数都需要去定义下,因为我想做一个通用的函数、过程调用,不知道有没有好的方法!这问题折腾了我很久了!
因为在sql server查询分析器中是可以直接调用 exec sp_test_z @oc_date = 20080722,@oc1_date = 20080724;而oracle里面无法做到,不知道
declare p_cursor t_cursor begin end;这样的pl/sql语句中的游标是否能够通过ADO控件的dataset返回?请各位大大给小弟一些建议!痛苦啊!分数不是问题,如果解决问题,我可以给出500分及以上!谢谢,如果用OCI接口或者ODAC能解决的话,也可以提供下方式,ODAC毕竟要收费的,希望是OCI接口解决
...全文
186 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
tianhxk 2008-08-04
  • 打赏
  • 举报
回复
结贴了!这个问题困扰了我很久了!以后也只能用这个方法了!对了,自己可以写一个接口!我再去弄个!
tianhxk 2008-08-04
  • 打赏
  • 举报
回复
也只能这样了!昨天晚上花了5个小时搞定了!一个一个的传参,然后所有的参数都传值NULL,再将其他值传进去,给其他人一个参考吧!
sParamdef ---代表 (?,?,?)

---获取函数或者过程对应的参数列表

' select a.argument_name as name, '
+' case '
+' when data_type = ''VARCHAR2'' then ''ftString'''
+' when data_type = ''CHAR'' then ''ftString'''
+' when data_type = ''NUMBER'' then ''ftFloat'''
+' when data_type = ''INTEGER'' then ''ftInteger'''
+' else ''ftString'' end as data_type, '
+' case '
+ ' when in_out = ''IN'' then ''pdInput'''
+ ' else ''pdOutput'' end as inout,'
+ ' data_length '
+' from user_arguments a '
+' where data_type <> ''REF CURSOR'''
+' and position > 0 '
+' and object_name = upper(''' + Trim(MenuInfo.SpName) + ''')'
+' order by position ';
---------调用
AdoQry.SQL.Add('{?= call ' + Trim(MenuInfo.spName) + '(' + sParamdef + ')}');
AdoQry.Parameters.Clear;
AdoQry.Parameters.CreateParameter('p_RETURN',ftinteger, pdReturnvalue,4,0);
for iCir:= 0 to length(AParamInfo)-1 do
begin
AdoQry.Parameters.CreateParameter(AParamInfo[iCir].Param_Name,AParamInfo[iCir].Param_type,
AParamInfo[iCir].Param_direction,AParamInfo[iCir].Param_length,null);
//if AparamInfo[iCir].Param_type = ftString then
//AdoQry.Parameters.ParamByName(AparamInfo[iCir].Param_Name).value := ' '
//else
AdoQry.Parameters.ParamByName(AparamInfo[iCir].Param_Name).value :=null;
end;

aawwmate 2008-07-30
  • 打赏
  • 举报
回复
明确告诉你,只能这样传参,并且顺序必须一致,别无他法. 除非自己写低层接口
僵哥 2008-07-24
  • 打赏
  • 举报
回复
有一个方法可以解决,通过程序自动刷新存储过程当中的参数,即通过搜索系统表找出所有除ref cursor以外的参数,然后创建起来,做一个类似mssql所支持的Parameters.Refresh.

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧