Please help with buffers for temp table

I have a problem with BUFFERs, it seems like I don't understand the philosophy of buffers or I am doing something wrong.

What I like to do is to create temp table, then two buffers for this temp table. In this two buffers I would like to keep two different records and modify them.

Please look below how I was trying to do this.

/* temp table definition - Vendor table is DB table*/
DEFINE TEMP-TABLE ttVendorOrig LIKE Vendor
FIELD TypRek AS CHARACTER FORMAT "X(1)" INITIAL ""
INDEX TypRekordu IS UNIQUE TypRek.

/* First Buffer */
DEFINE BUFFER ttVendorOrig1 FOR ttVendorOrig.
DEFINE VARIABLE httVendorOrig1 AS HANDLE NO-UNDO.
httVendorOrig1 = TEMP-TABLE ttVendorOrig1:DEFAULT-BUFFER-HANDLE.
httVendorOrig1:BUFFER-CREATE.
httVendorOrig1:BUFFER-FIELD("TypRek"):BUFFER-VALUE = "B".

/* Secound Buffer */
DEFINE BUFFER ttVendorOrig2 FOR ttVendorOrig.
DEFINE VARIABLE httVendorOrig2 AS HANDLE NO-UNDO.
httVendorOrig2 = TEMP-TABLE ttVendorOrig2:DEFAULT-BUFFER-HANDLE.
httVendorOrig2:BUFFER-CREATE.
httVendorOrig2:BUFFER-FIELD("TypRek"):BUFFER-VALUE = "P".

/* At this point I should have two buffers
with two different Values for TypRek field,
so I am checking if my assumption is true */

OUTPUT TO VALUE('my_file.txt')
MESSAGE httVendorOrig1:BUFFER-FIELD("TypRek"):BUFFER-VALUE.
MESSAGE httVendorOrig2:BUFFER-FIELD("TypRek"):BUFFER-VALUE.
OUTPUT CLOSE.

Unfortunatelly BOTH TypRek having 'P' value, instead of having 'P' and 'B' - and I don't know why. I will be very appreciated if someone can explain it to me and give some hint to resolve it.
 

FrancoisL

Member
Your are creating 2 new buffer for your temp-table then overwritting them with the handle of the default buffer handle of your temp-table. So both your handle point to the same BUFFER .

This code will do what you are trying to accomplish

Code:
DEFINE TEMP-TABLE ttVendorOrig LIKE vendor
FIELD TypRek AS CHARACTER FORMAT "X(1)" INITIAL ""
INDEX TypRekordu IS UNIQUE TypRek.

/* First Buffer */
DEFINE BUFFER ttVendorOrig1 FOR ttVendorOrig.
DEFINE VARIABLE httVendorOrig1 AS HANDLE NO-UNDO.
httVendorOrig1 = BUFFER ttVendorOrig1:HANDLE.
httVendorOrig1:BUFFER-CREATE.
httVendorOrig1:BUFFER-FIELD("TypRek"):BUFFER-VALUE = "B".

/* Secound Buffer */
DEFINE BUFFER ttVendorOrig2 FOR ttVendorOrig.
DEFINE VARIABLE httVendorOrig2 AS HANDLE NO-UNDO.
httVendorOrig2 = BUFFER ttVendorOrig2:HANDLE.
httVendorOrig2:BUFFER-CREATE.
httVendorOrig2:BUFFER-FIELD("TypRek"):BUFFER-VALUE = "P".

/* At this point I should have two buffers
with two different Values for TypRek field,
so I am checking if my assumption is true */


OUTPUT TO VALUE('my_file.txt')
MESSAGE httVendorOrig1:BUFFER-FIELD("TypRek"):BUFFER-VALUE.
MESSAGE httVendorOrig2:BUFFER-FIELD("TypRek"):BUFFER-VALUE.
    OUTPUT CLOSE.
 

tamhas

ProgressTalk.com Sponsor
One might note that you also have more buffers here than you need since there is a default buffer for the temp-table that has the same name as the temp-table.

Some notion of what you are trying to accomplish here might also lead to different suggestions. I.e., what do you want to do that is not achieved by:

Code:
DEFINE TEMP-TABLE ttVendorOrig LIKE vendor
FIELD TypRek AS CHARACTER FORMAT "X(1)" INITIAL ""
INDEX TypRekordu IS UNIQUE TypRek.

/* First Buffer */
DEFINE BUFFER ttVendorOrig1 FOR ttVendorOrig.

create ttVendorOrig.
assign ttVendorOrig.TypRek = "B".

create ttVendorOrig1.
assign ttVendorOrig.TypRek = "P".

In particular, it is not clear why you are wanting two buffers here. The usual thing is to have some set of data, often where one record links to another record within the same table, find or iterate on one buffer, and then use the other buffer to get at the one(s) linked to. The other common use of additional buffers, although less typical for temp-tables, is to loop through a table with NO-LOCK, identify a record of interest, and use the second buffer to read the same record with EXCLUSIVE-LOCK.

We might have different suggestions if we knew your context.
 

FrancoisL

Member
I think he wanted to have two distinct buffers to keep pointers on both records at the same time. Probably modification in one affects the second one.

I believe that this was more about learning how buffers work then how to create two records in the database.
 

tamhas

ProgressTalk.com Sponsor
Point being, though, that there are three buffers in the example, not just two.

And, frankly, it is hard to tell what the purpose is from the example. It always helps to know that because one can often come up with an entirely different approach which is better.
 
Your are creating 2 new buffer for your temp-table then overwritting them with the handle of the default buffer handle of your temp-table. So both your handle point to the same BUFFER .

This code will do what you are trying to accomplish..."

Thank you for explanation. I am new to 4GL and I thought that DEFAULT-BUFFER-HANDLE will be a default HANDLE for buffer and not for table for which I have created a buffer. One more time - thank you.
 

enoon

Member
Thank you for explanation. I am new to 4GL and I thought that DEFAULT-BUFFER-HANDLE will be a default HANDLE for buffer and not for table for which I have created a buffer. One more time - thank you.

Also you used dynamic attribute of a temp-table that is defined statically, which is confusing for the developer and not the best practice.
Help - "Like static temp-tables, every dynamic temp-table is created with at least one buffer. This buffer’s object handle is returned by this attribute."
 
One might note that you also have more buffers here than you need since there is a default buffer for the temp-table that has the same name as the temp-table.

I know about this additional buffer, but I did it on purpose. I don't want to be confused so I created buffer named ttVendorOrig1 and ttVendorOrig2.


Some notion of what you are trying to accomplish here might also lead to different suggestions. I.e., what do you want to do that is not achieved by:

Code:
DEFINE TEMP-TABLE ttVendorOrig LIKE vendor
FIELD TypRek AS CHARACTER FORMAT "X(1)" INITIAL ""
INDEX TypRekordu IS UNIQUE TypRek.

/* First Buffer */
DEFINE BUFFER ttVendorOrig1 FOR ttVendorOrig.

create ttVendorOrig.
assign ttVendorOrig.TypRek = "B".

create ttVendorOrig1.
assign ttVendorOrig.TypRek = "P".

I need to use HANDLE's as it allows to me use :NUM-FIELDS and :NAME attributes of filed. This is why I created a TEMP-TABLES. As I said before I am new to 4GL and sometimes I am not using the best approach, I am using the one I know about it :).

In particular, it is not clear why you are wanting two buffers here. The usual thing is to have some set of data, often where one record links to another record within the same table, find or iterate on one buffer, and then use the other buffer to get at the one(s) linked to. The other common use of additional buffers, although less typical for temp-tables, is to loop through a table with NO-LOCK, identify a record of interest, and use the second buffer to read the same record with EXCLUSIVE-LOCK.

We might have different suggestions if we knew your context.
The whole scenario I am trying to do is like following:

I have a table ChgLog in DB where all changes to the fields are in something called LogText. It is a CHARACTER field and data inside this file is organized like:
"UserName TimeOfChange LabelOfDBField OldValue '->' NewValue"

This table is filled out by external application (not mine). I am writing a 4GL that will analyze this change log. So I need three buffers (One for storing current data for one Vendor, Second for storing the data when Vendor was created, Third for storing STATUS)

First two buffers are should be the same as Vendor table in DB, third buffer should have the same FieldNames and Labels for fields like Vendor table but FORMAT of all fields should be CHARACTER "X(1)".

I don't know what was data of Vendor when it was created, but I know the current data an all changes. So I am going through changeLog. Checking for first change of each field in LogText (marking this change in buffer3 as "1") and copying the content of that field from buffer1 to buffer2. If there is another change in that field then after checking the status of buffer3, I know then if there is a "1" then I already have the first change captured.

In this way I am trying to recreate the Vendor Data from the moment of creation.
 
I think he wanted to have two distinct buffers to keep pointers on both records at the same time. Probably modification in one affects the second one.

I believe that this was more about learning how buffers work then how to create two records in the database.

You are right, I want to keep two 'independent' buffers or pointers to this buffers so I can access and change data in each buffer in any place of my procedure.
 

tamhas

ProgressTalk.com Sponsor
OK, but what about this is requiring the dynamic temp-table references? It sounds to me like you know all the fields and such. Why not do it all statically?
 
OK, but what about this is requiring the dynamic temp-table references? It sounds to me like you know all the fields and such. Why not do it all statically?

This is because the change log doesn't hold the fieldnames - it holds the LABEL attribute of field.
So in Change Log I have 'Primary Bank ID', and the filename of Vendor table is 'PrimBankID'.

The other thing is - I can't refer to DB table fieldname using variable, and I don't know if it is possilbe. i.e
MyVariable='PrimBankID'
Vendor.'MyVariable'
do you know how to do such thing?
 
Top