PowerBuilder 12.5 SQL游标事务大小错误

问题描述:

我有一个主要问题,并试图找到一种解决方法。我有一个在PB12.5中的应用程序,在SQL和oracle数据库上工作..(与大量的数据)PowerBuilder 12.5 SQL游标事务大小错误

我使用CURSOR在一个点,但只有在SQL应用程序崩溃。在PB中使用调试我发现sql连接由于事务大小巨大而退缩-1。但我想逐行读取我的数据..是任何解决数据如寻呼的工作?我的意思是让我们取下第一个1000行,然后是其他1000行,等等..我希望你明白我想实现的目标(如果可能的话,打破获取过程并因此减少交易规模),这里是我的代码

DECLARE trans_Curs CURSOR FOR 
SELECT associate_trans.trans_code 
FROM associate_trans 
WHERE associate_trans.usage_code = :ggs_vars.usage ORDER BY associate_trans.trans_code ; 

    OPEN trans_Curs; 
    FETCH trans_Curs INTO :ll_transId; 

    DO WHILE sqlca.sqlcode = 0 
    ll_index += 1 
     hpb_1.Position = ll_index 
     if not guo_associates.of_asstrans_updatemaster(ll_transId, ls_error) then 
     ROLLBACK; 
     CLOSE trans_Curs; 
     SetPointer(Arrow!) 
     MessageBox("Update Process", "Problem with the update process on~r~n" + sqlca.sqlerrtext) 
    cb_2.Enabled = TRUE 
    return 
end if 
FETCH trans_Curs INTO :ll_transId; 
LOOP 
CLOSE trans_Curs; 
+0

您可以添加限制你的查询有两个值,开始和结束的条件(例如,启动条件是当前时间戳 - 它相关,否则其他任何相关条件;结束条件是行数后,第一个结果,获取时间戳(或选定的值)作为开始条件,并重新发出具有相同行数的select。等等...... – FDavidov

+0

谢谢FDavidov对你的文章,你能给我一个例子,样本? – dc03kks

+0

太长的评论,所以我会在几分钟内把它作为答案。 – FDavidov

首先感谢FDavidov为您的努力,所以我设法使用动态数据存储而不是光标,所以这里是我的解决方案,以防别人需要这个。

String ls_sql, ls_syntax, ls_err 
    Long ll_row 
    DataStore lds_info  

    ls_sql = "SELECT associate_trans.trans_code " & 
       + " FROM associate_trans " & 
       + " WHERE associate_trans.usage_code = '" + ggs_vars.usage +"' "& 
       + " ORDER BY associate_trans.trans_code" 
    ls_syntax = SQLCA.SyntaxFromSQL(ls_sql, "", ls_err) 

    IF ls_err <> '' THEN 
    MessageBox('Error...', ls_err) 
    RETURN 
    END IF 

    lds_info = CREATE DataStore 
    lds_info.Create(ls_syntax, ls_err) 
    lds_info.SetTransObject(SQLCA) 
    lds_info.Retrieve()   

     DO WHILE sqlca.sqlcode = 0 and ll_row <= ll_count    
       FOR ll_row = 1 TO ll_count 
        ll_transId = lds_info.GetItemNumber(ll_row, 'trans_code')       
         ll_index += 1 
         hpb_1.Position = ll_index 
         do while yield(); loop 
         if not guo_associates.of_asstrans_updatemaster(ll_transId, ls_error) then 
          ROLLBACK; 
          DESTROY lds_info 
          SetPointer(Arrow!) 
          MessageBox("Update Process", "Problem with the update process on~r~n" + sqlca.sqlerrtext) 
          cb_2.Enabled = TRUE 
          return 
         end if    
        NEXT 
        DESTROY lds_info      
     LOOP   
+0

它是与我最初的问题不同的方法,但迄今为止是游标问题中的最佳解决方案! – dc03kks

由于源表的结构没有完全显示,我会在这里做一些假设。

我们假设这些记录包含一个可以用作参考的独特字段(可以是计数器或时间戳)。我会在这里假设该字段是一个时间戳。我们还假设PB接受带参数的游标(并非所有的解决方案都行;如果不行,则有简单的解决方法)。

你可以修改你的光标是这样的:

[注:我也假设,这里介绍的语法是有效的为您的环境;如果不是,修改是简单]

DECLARE TopTime TIMESTAMP ; 
DECLARE trans_Curs CURSOR FOR 
     SELECT ots.associate_trans.trans_code 
      FROM ots.associate_trans 
      WHERE ots.associate_trans.usage_code = :ggs_vars.usage 
      AND ots.associate_trans.Timestamp < TopTime 
      ORDER BY ots.associate_trans.trans_code 
      LIMIT 1000 ; 
: 
: 
IF (p_Start_Timestamp IS NULL) THEN 
    TopTime = CURRENT_TIMESTAMP() ; 
ELSE 
    TopTime = p_Start_Timestamp ; 
END IF ; 

OPEN trans_Curs; 
FETCH trans_Curs INTO :ll_transId; 
: 
: 

在上述:

  1. p_Start_Timestamp是这将最初是空的,然后将包含OLDEST时间戳取在先前调用中接收的时间戳参数,

  2. CURRENT_TIMESTAMP()是您的环境返回当前时间戳的函数。

该解决方案将单独工作时,你需要在一个方向(即从现在到过去的)进步和您所积累的所有提取的记录在内部缓冲区的情况下,你需要滚动再升。

希望这可以让事情更清楚。

+0

谢谢FDavidov您的帖子。但是,这是一件事,我的表ots.associate_trans没有唯一的字段,除了trans_code。所以不存在计数器或时间戳字段。如果他们存在,一切都会更容易。所以这个答案不幸的是不适用。 – dc03kks

+0

我试图用row_number而不是游标的解决方法,但这只适用于sql,在oracle中它不工作,也似乎我的游标事务大小问题只发生在sql中。 – dc03kks

+0

你没有提到它是Oracle。您使用的是哪个版本的Oracle? – FDavidov