PowerBuilder 12.5 sql 游标事务大小错误
PowerBuilder 12.5 sql cursors transaction size error
我遇到了一个主要问题,正在尝试寻找解决方法。我在 PB12.5 中有一个应用程序,它适用于 sql 和 oracle dbs..(有很多数据)
我在某个时候使用了 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;
由于您的来源 table 的结构没有完全呈现,我将在这里做一些假设。
我们假设记录包含一个可用作参考的唯一字段(可以是计数器或时间戳)。我在这里假设该字段是一个时间戳。
我们还假设 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;
:
:
在上面:
p_Start_Timestamp
是接收到的时间戳参数,最初为空,然后将包含上次调用中获取的 OLDEST 时间戳,
CURRENT_TIMESTAMP()
是您的环境返回当前时间戳的函数。
只有当您需要朝一个方向(即从现在到过去)前进并且您正在将所有获取的记录累积在内部缓冲区中以防您需要滚动又起来了
希望这能让事情更清楚。
首先感谢 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
我遇到了一个主要问题,正在尝试寻找解决方法。我在 PB12.5 中有一个应用程序,它适用于 sql 和 oracle dbs..(有很多数据)
我在某个时候使用了 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;
由于您的来源 table 的结构没有完全呈现,我将在这里做一些假设。
我们假设记录包含一个可用作参考的唯一字段(可以是计数器或时间戳)。我在这里假设该字段是一个时间戳。
我们还假设 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;
:
:
在上面:
p_Start_Timestamp
是接收到的时间戳参数,最初为空,然后将包含上次调用中获取的 OLDEST 时间戳,CURRENT_TIMESTAMP()
是您的环境返回当前时间戳的函数。
只有当您需要朝一个方向(即从现在到过去)前进并且您正在将所有获取的记录累积在内部缓冲区中以防您需要滚动又起来了
希望这能让事情更清楚。
首先感谢 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