PowerBuilder中在调用oracle存储过程时,如何使用绑定变量?

IndependentDeveloper 2009-09-04 04:49:21
在oracle的SQL追踪中发现大量如下记录:

BEGIN TheCompChargeVerify( ParmComp => '15049910024408' , ParmNeedPayNo => '200909041141
41' , ParmCycle => '199805' , ParmInsure => '020101' , ParmFlag => '0' , ParmOperator => 'sa2'
,RETERRTEXT=>:RETERRTEXT,RETERR=>:RETERR); END;
/
BEGIN TheCompChargeVerify( ParmComp => '15049910024408' , ParmNeedPayNo => '200909041141
41' , ParmCycle => '199805' , ParmInsure => '020301' , ParmFlag => '0' , ParmOperator => 'sa2'
,RETERRTEXT=>:RETERRTEXT,RETERR=>:RETERR); END;
/
BEGIN TheCompChargeVerify( ParmComp => '15049910024408' , ParmNeedPayNo => '200909041141
41' , ParmCycle => '199806' , ParmInsure => '020101' , ParmFlag => '0' , ParmOperator => 'sa2'
,RETERRTEXT=>:RETERRTEXT,RETERR=>:RETERR); END;
/
BEGIN TheCompChargeVerify( ParmComp => '15049910024408' , ParmNeedPayNo => '200909041141
41' , ParmCycle => '199806' , ParmInsure => '020301' , ParmFlag => '0' , ParmOperator => 'sa2'
,RETERRTEXT=>:RETERRTEXT,RETERR=>:RETERR); END;
/
BEGIN TheCompChargeVerify( ParmComp => '15049910024408' , ParmNeedPayNo => '200909041141
41' , ParmCycle => '199807' , ParmInsure => '020101' , ParmFlag => '0' , ParmOperator => 'sa2'
,RETERRTEXT=>:RETERRTEXT,RETERR=>:RETERR); END;
/
......

根据这个记录,我估计是开发人员绑定变量使用的有问题,导致出现大量此类记录
这段代码是通过PB调用的
我对PB一点都不懂,PB开发人员给的调用代码如下:

string Ls_RetErrText,ls_ID,ls_aka_append,ls_AAE140,ls_AAE002
int Li_RetErr
long ll_rows,ll_row

DECLARE TheCompChargeVerifyePro PROCEDURE FOR TheCompChargeVerify
( ParmComp => :parmcomp,
ParmNeedPayNo => :ls_ID,
ParmCycle => :ls_AAE002,
ParmInsure => :ls_AAE140,
ParmFlag => :ls_aka_append,
ParmOperator => :ThisCurrEmpPurData.oper_name
)
USING SQLCA;

for ll_row = 1 to ll_rows
if dw_n.getitemnumber(ll_row,'flag') = 1 then
ls_ID = dw_n.getitemstring(ll_row,'ID')
ls_aka_append = dw_n.getitemstring(ll_row,'aka_append')
ls_AAE140 = dw_n.getitemstring(ll_row,'AAE140')
ls_AAE002 = dw_n.getitemstring(ll_row,'AAE002')

EXECUTE TheCompChargeVerifyePro;

if sqlca.sqlcode < 0 then
lasterrtext = 'Source:t_comp_needpay_system->thecompchargeverify:调用单位缴费到帐复核过程时出错:' + sqlca.sqlerrtext
ROLLBACK USING SQLCA;
CLOSE TheCompChargeVerifyePro;
return false
end if

FETCH TheCompChargeVerifyePro INTO :Ls_RetErrText,:Li_RetErr;
CLOSE TheCompChargeVerifyePro;

if Li_RetErr <> 1 then
lasterrtext = '调用单位到帐复核过程时出错,错误编码为( ' + string( Li_RetErr ) + ' ),错误原因为:' + Ls_RetErrText
ROLLBACK USING SQLCA;
RETURN FALSE;
end if

end if;
next

COMMIT USING SQLCA;

return true

上边的代码有什么问题吗?希望高手帮忙看看,不胜感激!
...全文
343 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
leio 2009-09-08
  • 打赏
  • 举报
回复
可否将存储过程改写一下,在PB中将dw_n里的数据写入一个临时表,然后调用存储过程,在存储过程中访问这个临时表里的相关数据,最终一次性返回结果集,而不是象现在这样调用一次存储过程只返回一个结果。
  • 打赏
  • 举报
回复
相信这里应该有用PB+oracle开发产品经验的人,希望能分享一下在绑定变量上究竟是怎么解决这个问题的,非常感谢!
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 leio 的回复:]
这个有什么问题吗?按照代码来看就是应该有这么多SQL记录才对,没有的话才真是有问题了。

for ll_row = 1 to ll_rows
    if dw_n.getitemnumber(ll_row,'flag') = 1 then

这里是个循环,从1循环到ll_rows,如果flag=1,每次循环都会执行一次TheCompChargeVerifyePro,那么在ORACLE中就会产生一次SQL执行记录。
[/Quote]
问题就在于每一次调用TheCompChargeVerify传递的是具体的值,而oracle在处理这种语句时必须进行一次硬解析,当此类调用很频繁时,性能直线下降,我查询追踪记录时发现,此类调用的executions值全都是1,也就是说只使用了一次,频繁的争夺CPU时间,并抢用latch,并且最麻烦的是把executions很高的SQL挤出share_pool.不知道我这么说,能明白吗?有些词我实在不知道用中文怎么说贴切......
leio 2009-09-08
  • 打赏
  • 举报
回复
这个有什么问题吗?按照代码来看就是应该有这么多SQL记录才对,没有的话才真是有问题了。

for ll_row = 1 to ll_rows
if dw_n.getitemnumber(ll_row,'flag') = 1 then

这里是个循环,从1循环到ll_rows,如果flag=1,每次循环都会执行一次TheCompChargeVerifyePro,那么在ORACLE中就会产生一次SQL执行记录。
  • 打赏
  • 举报
回复
版主有这方面的经验吗?分享一下,谢谢了
  • 打赏
  • 举报
回复
oracle那边也解决不了,又移回来了......
qin_phoenix 2009-09-08
  • 打赏
  • 举报
回复
帮你顶。。。
leio 2009-09-08
  • 打赏
  • 举报
回复
楼主你和你那里的PB开发人员沟通一下,让他在PB中打开DATABASE画板

Database Profile Setup->Transaction
将“Bind Procedure Parameters”选中,然后你在ORACLE中在跟踪一下看看。

  • 打赏
  • 举报
回复
[Quote=引用 16 楼 leio 的回复:]
可否将存储过程改写一下,在PB中将dw_n里的数据写入一个临时表,然后调用存储过程,在存储过程中访问这个临时表里的相关数据,最终一次性返回结果集,而不是象现在这样调用一次存储过程只返回一个结果。
[/Quote]
跟开发人员沟通了一下,说不可行,主要考虑的是不使用游标.
哎......没办法,我只好把oracle的cursor_sharing改成force,测试一段时间看看,据说这个参数不稳定,这回自己测试吧,这帖子结了,感谢大家的帮助,虽然问题没解决!
道儿仙 2009-09-07
  • 打赏
  • 举报
回复
学习中...
帮你顶一下!
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hgx321 的回复:]
这样试试,把定义放到循环里看看


SQL code
string Ls_RetErrText,ls_ID,ls_aka_append,ls_AAE140,ls_AAE002
int Li_RetErr
long ll_rows,ll_row

   

for ll_row = 1 to ll_rows
    if dw_n.getitemnumber(ll_row,'flag') = 1 then
        ls_ID        = dw_n.getitemstring(ll_row,'ID')
        ls_aka_append = dw_n.getitemstring(ll_row,'aka_append')
        ls_AAE140    = dw_n.getitemstring(ll_row,'AAE140')
        ls_AAE002    = dw_n.getitemstring(ll_row,'AAE002')
       
DECLARE TheCompChargeVerifyePro PROCEDURE FOR TheCompChargeVerify
            ( ParmComp      => :parmcomp,
          ParmNeedPayNo => :ls_ID,
          ParmCycle    => :ls_AAE002,
          ParmInsure    => :ls_AAE140,
          ParmFlag      => :ls_aka_append,
          ParmOperator  => :ThisCurrEmpPurData.oper_name
        ) 
      USING SQLCA;   

        EXECUTE TheCompChargeVerifyePro;
       
        if sqlca.sqlcode < 0 then
            lasterrtext = 'Source:t_comp_needpay_system->thecompchargeverify:调用单位缴费到帐复核过程时出错:' + sqlca.sqlerrtext
            ROLLBACK USING SQLCA;
            CLOSE TheCompChargeVerifyePro;
            return false
        end if
       
        FETCH TheCompChargeVerifyePro INTO :Ls_RetErrText,:Li_RetErr;
        CLOSE TheCompChargeVerifyePro;
       
        if Li_RetErr <> 1 then
            lasterrtext = '调用单位到帐复核过程时出错,错误编码为( ' + string( Li_RetErr ) + ' ),错误原因为:' + Ls_RetErrText
            ROLLBACK USING SQLCA;
            RETURN FALSE;
        end if

    end if;
next 

COMMIT USING SQLCA; 

return true


[/Quote]
谢谢帮助,还是出现类似问题......放到循环里边也一样
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qin_phoenix 的回复:]
修改存储过程,传时间段进去
[/Quote]
谢谢你的回复,你的意思是不是传范围进去?
我的意思是pb的调用代码如果能变成类似下边的代码:

BEGIN TheCompChargeVerify( ParmComp => :1 , ParmNeedPayNo => :2, ParmCycle => :3 , ParmInsure => :4 , ParmFlag => :5 , ParmOperator => :6 ,RETERRTEXT=>:RETERRTEXT,RETERR=>:RETERR); END;

就完美了,PB调用不能实现这样吗?
qin_phoenix 2009-09-07
  • 打赏
  • 举报
回复
修改存储过程,传时间段进去
qin_phoenix 2009-09-07
  • 打赏
  • 举报
回复
COMMIT USING SQLCA;  
放在循环中提交可以吗?
这些代码看起来还熟悉,是“金宝工程”
  • 打赏
  • 举报
回复
我转了一下帖子,结贴率竟然变成87.50%了......
  • 打赏
  • 举报
回复
在PB那里没人回答,只好转到oracle这里了,谁有类似经验帮忙分享一下,谢谢了
hgx321 2009-09-05
  • 打赏
  • 举报
回复
这样试试,把定义放到循环里看看


SQL code
string Ls_RetErrText,ls_ID,ls_aka_append,ls_AAE140,ls_AAE002
int Li_RetErr
long ll_rows,ll_row



for ll_row = 1 to ll_rows
if dw_n.getitemnumber(ll_row,'flag') = 1 then
ls_ID = dw_n.getitemstring(ll_row,'ID')
ls_aka_append = dw_n.getitemstring(ll_row,'aka_append')
ls_AAE140 = dw_n.getitemstring(ll_row,'AAE140')
ls_AAE002 = dw_n.getitemstring(ll_row,'AAE002')

DECLARE TheCompChargeVerifyePro PROCEDURE FOR TheCompChargeVerify
( ParmComp => :parmcomp,
ParmNeedPayNo => :ls_ID,
ParmCycle => :ls_AAE002,
ParmInsure => :ls_AAE140,
ParmFlag => :ls_aka_append,
ParmOperator => :ThisCurrEmpPurData.oper_name
)
USING SQLCA;

EXECUTE TheCompChargeVerifyePro;

if sqlca.sqlcode < 0 then
lasterrtext = 'Source:t_comp_needpay_system->thecompchargeverify:调用单位缴费到帐复核过程时出错:' + sqlca.sqlerrtext
ROLLBACK USING SQLCA;
CLOSE TheCompChargeVerifyePro;
return false
end if

FETCH TheCompChargeVerifyePro INTO :Ls_RetErrText,:Li_RetErr;
CLOSE TheCompChargeVerifyePro;

if Li_RetErr <> 1 then
lasterrtext = '调用单位到帐复核过程时出错,错误编码为( ' + string( Li_RetErr ) + ' ),错误原因为:' + Ls_RetErrText
ROLLBACK USING SQLCA;
RETURN FALSE;
end if

end if;
next

COMMIT USING SQLCA;

return true

  • 打赏
  • 举报
回复
有在PB中使用绑定变量经验的人吗?帮忙分享一下经验,不胜感激!

754

社区成员

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

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