我目前搞定的方式是用 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接口解决

解决方案 »

  1.   

    有一个方法可以解决,通过程序自动刷新存储过程当中的参数,即通过搜索系统表找出所有除ref cursor以外的参数,然后创建起来,做一个类似mssql所支持的Parameters.Refresh.
      

  2.   

    也只能这样了!昨天晚上花了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;