1. Aron Cox
  2. PowerBuilder
  3. Thursday, 29 October 2020 11:27 AM UTC

PowerBuilder 2017 R2 Build 1769

Blob size = Len(lblob)

We have a window which retrieves multiple reports in one go and then using a single datawindow allows the user to switch between the reports as required. We do this by saving each report into an array of blobs using GetFullState, switchign them back in tp the datawindow using SetFullState. This has been working fine for years.

A customer seems to have reached a blob size limitation on one of the reports. GetFullState returns the correct number of rows, but the blob has a length of 0, using it to do a SetFullState returns -1 because, of course, the blob has a length of 0.

I tried removing rows until it worked, and it seems as long as the blob size is less than 100,000,000 it works but when it goes over it stops working.

So,

* Anyone know if this is a max size for GetItemString?

* If it is, then is there a way to change it?

* Anything else I can do to save a datawindow and reshow it other than having invisible datawindows and showing them when applicable. The formatting can be chaged on the fly, and so needs to be part of the save, not just the rows. I assume dw_2 = dw_1 doesn't copy dw_1 but just points to it?

Here's my test code and results. I am testing by using RowsCopy to copy the data to a temporary datastore, then doing a GetFullState, and logging the results

 

lds.Reset()
ll_ret = adw.RowsCopy(1, 40000, Primary!, lds, 1, Primary!)
f_pblog("w_rep_client_statement_old", location, " Tried again using RowsCopy with 40000 rows, rc = " + String(ll_ret))
f_pblog("w_rep_client_statement_old", location, " Rows in lds = " + String(lds.RowCount()))
lblob = lblob_null
ll_ret = lds.GetFullState(lblob)
f_pblog("w_rep_client_statement_old", location, " GetFullState rc = " + String(ll_ret))
f_pblog("w_rep_client_statement_old", location, " Blob extracted from datastore has a length of " + String(Len((lblob))))

lds.Reset()
ll_ret = adw.RowsCopy(1, 50000, Primary!, lds, 1, Primary!)
f_pblog("w_rep_client_statement_old", location, " Tried again using RowsCopy with 50000 rows, rc = " + String(ll_ret))
f_pblog("w_rep_client_statement_old", location, " Rows in lds = " + String(lds.RowCount()))
lblob = lblob_null
ll_ret = lds.GetFullState(lblob)
f_pblog("w_rep_client_statement_old", location, " GetFullState rc = " + String(ll_ret))
f_pblog("w_rep_client_statement_old", location, " Blob extracted from datastore has a length of " + String(Len((lblob))))

Results:

Works fine with 40,000 rows and results in a blob size of just under 100,000,000

Tried again using RowsCopy with 40000 rows, rc = 1
Rows in lds = 40000
GetFullState rc = 40000
Blob extracted from datastore has a length of 96086718

 

Fails with 50,000 rows, get GetFullState does return the correct row count, just a blob size of 0

Tried again using RowsCopy with 50000 rows, rc = 1
Rows in lds = 50000
GetFullState rc = 50000
Blob extracted from datastore has a length of 0

 

Any thoughts are welcome! Thank you!

Aron Cox Accepted Answer Pending Moderation
  1. Friday, 30 October 2020 10:22 AM UTC
  2. PowerBuilder
  3. # 1
0
Votes
Undo

Thought I'd add an update on what seems to be going on in case anyone finds this in the future .

After a little more testing:

* PowerBuilder 2019 R2 2353
Still fails too easily, but does appear to always have the correct return code of -1. It does however, as with 2017, not reset the blob to a zero length blob, so it still contains the data from the previous working call, which could catch people out.


      Adding 45,000 rows to the datawindow
      Added 45,000 rows to the datawindow
      Doing a GetFullState
      The return code from the GetFullState was: -1
      Blob size from the GetFullState was: 641,462 <= This is from an earlier call using the same blob

* PowerBuilder 2017 R2 1769
Sometimes returns -1 sometimes returns the correct row count even though it has failed
If you call it twice in a row with the same blob, the first one with a small amount of rows so it works and fills the blob, the second one with too many rows so it fails you can end up with the following. It failed but the return code gives a success number of rows and blob still contains the data from the previous working call


      Adding 30,000 rows to the datawindow
      Added 30,000 rows to the datawindow
      Doing a GetFullState
      The return code from the GetFullState was: 30000 <= It actually failed to set the blob, but looks like it worked!
      Blob size from the GetFullState was: 641,438 <= Previous calls blob

Comment
There are no comments made yet.
mike S Accepted Answer Pending Moderation
  1. Thursday, 29 October 2020 15:31 PM UTC
  2. PowerBuilder
  3. # 2
1
Votes
Undo

ALTERNATE method:

instead of using blobs, run the reports in datastores.

 

To display, just copy the datastore report format to the datawindow, then SHARE the datastore to the datawindow.

ids_data is the report that is run, dw_REPORTview is what the user will see:

 

ls_def = ids_data.object.datawindow.syntax

dw_REPORTview.create( ls_def, ls_error)

ll_rc = ids_data.ShareData ( dw_REPORTview )

 

Comment
Thnaks, not something I've done before. What about sorting and grouping, will they be automatically included or do I need to reapply them?
  1. Aron Cox
  2. Thursday, 29 October 2020 18:40 PM UTC
you are making a copy of the datawindow syntax as it is at runtime. if the syntax has grouping and sorting then the copy has sorting and grouping. It goes beyond that, if you have any runtime customizations that are applied to the report, then when you copy the report the copy has the runtime customizations. that is the difference between using syntax/CREATE vs using .dataobject =



  1. mike S
  2. Thursday, 29 October 2020 19:00 PM UTC
Excellent, thank you
  1. Aron Cox
  2. Friday, 30 October 2020 08:10 AM UTC
There are no comments made yet.
Kevin Ridley Accepted Answer Pending Moderation
  1. Thursday, 29 October 2020 11:51 AM UTC
  2. PowerBuilder
  3. # 3
0
Votes
Undo

https://community.appeon.com/index.php/qna/q-a/sql-server-and-pbmaxblobsize-in-pb-2017-r2

Comment
I wrote a small test application that inserts rows ito a datawindow and then calls GetFullState. I can get it to fail, i.e. a blob size of zero, with 10's of thousands of rows and three string(1000) columns. If I run it from a build I can do twice as many rows (or so), so it does seem to be memory dependent as said. However I'm not impressed that GetFullState is not as solid as I would've expected. What is a large number of rows in a datawindow? 10's of thousands doesn't seem all that many to me. It's also not an obvious failure as the return code is correct, the number of rows in the datawindow, just the blob is not.
  1. Aron Cox
  2. Thursday, 29 October 2020 15:15 PM UTC
If you're talking about 10's of thousands of rows, I'm guessing you don't need the full state then. How about creating a datastore, sharing with that and saving as a resultset? According to the documentation, the ds.GenerateResultSet function is obsolete because EA Server is no longer used, but this seems like a good use case for it. Try the ds.generateResultSet and then ds.CreateFrom on the other end. It should buy you some memory space without all the formatting and statuses, etc. Seems worth a shot.
  1. Kevin Ridley
  2. Thursday, 29 October 2020 15:27 PM UTC
Interesting, I've never even heard of GenerateResultSet! Thanks.
  1. Aron Cox
  2. Friday, 30 October 2020 08:11 AM UTC
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.