Changed by Another Station - debug code to track cause

There was a previous thread about this message w/ SQL in which the difficulty of tracking the cause was noted. Having again faced the problem recently, I revisited the situation in an attempt to come up with a debug option to help.

By adding a #pragma and code in the FileManager.EqualBuffer method, I can now easily see the first byte in the file record that appears as having been changed. However, w/ some tables, it can still be difficult to know the exact record field to which the changed byte corresponds.

For instance, if the debug code shows CHR(32) vs CHR(0) at byte 832 in the Clarion record buffer, is there an easy way to determine the relevant field name (other than manually adding up all the field sizes)? My recent tests using various combinations of WHO, WHERE have not been successful.

Here’s some bare-bones code with no error checking. You’d probably want to do a bit of error checking in real life. It makes use of my PrivateClass. https://github.com/jslarve/PrivateClass

                PROGRAM
                MAP
                END

INCLUDE('JSPrivateClass.inc')

JSP                 JSPrivateClass


G                   GROUP
F1                      STRING(30)
F2                      STRING(35)
F3                      STRING(900)
F4                      LONG
F5                      STRING(100)
                END

Ndx                 LONG

CODE
    
    LOOP Ndx = 1 TO 5
        IF JSP.GetAnyDataAddress(WHAT(G,Ndx)) - ADDRESS(G) > 832
            MESSAGE(WHO(G,Ndx-1))
            BREAK
        END
    END

Years ago I worked with MS SQL, the issue “Changed by another station” happened if sql table had time field. The reason of the issue is that Clarion loses time presicion and thinks that field value has been changed.

1 Like

Mike,

Yeah, I believe time has often been part of the problem. The trouble I am seeing now involves several timestamp columns in PostgreSQL. The FileManagerClass will save the buffer with a zero value and if SETNULL is used prior to the the EqualBuffer compare the Changed message results.

Douglas

Hello Douglas, I don’t know Postgres and don’t know your case, so I’m just wondering… maybe one of the column level driver switches (NoWhere and/or ReadOnly) could help you?
Take a look at “NOWHERE driver switch” in help.

Regards,
Andrzej

Your field in dictionary may shorter than DB field and if DB value size larger than dictionary field size that may cause your problem.

Also Mike’s date problem happened on my C6 applications. I used smalldatetime or cropped microseconds. But latest versions (after 9) that problem has solved.

Yes, I went through those string size issues awhile ago.
Fortunately, not the situation this time(stamp).

Consider the following:

SqlTs       STRING(8)
SqlTsGrp    GROUP,OVER
SqlDate       DATE
SqlTime       TIME
            END
IsReviewed  BYTE

IF IsReviewed = True
  SqlDate = TODAY()
  SqlTime = CLOCK()
ELSE
  ! Which code choice MUST be used to clear SqlTimestamp and avoid Changed by Another?
  ! CLEAR(SqlTimestamp)?
  ! SqlTimestamp = ''
  ! CLEAR(SqlDate) ; CLEAR(SqlTime) 
  ! SETNULL(SqlTimestamp)?
END

Hi Douglas,

Nothing you put there will make any difference, the error will still happen. Putting the NOWHERE driver switch on the SqlTS field should do fix your problem.

The problem comes from (as people have already pointed out)…

get(myfile)
WATCH(myfile) – saves a copy of the buffer for comparison later
…you make various changes to the file buffer
PUT(myfile)

Because of the watch, the Put first does:

select
from myfile
where <column_name1> = ?stored value1
and <column_name2> = ?stored_value2
etc.

Because the stored value was mangled or truncated in some way, the select fails to find the record, and that gives you the “Changed by…” error. In this case, presumably the time_stamp is truncated on being plonked into a clarion TIME.

Jon,

Hope to find time to test with NOWHERE later today.

However, what I see so far indicates that clearing SqlDate & SqlTime individually (as opposed to SqlTimestamp) does actually solve the problem.

What you note about watch/select makes sense to me but the select certainly does not appear to consistently fail.

Jon,

After more checking, it seems there is more to this than just Changed by Another Station.

How SqlDate & SqlTime are cleared comes into play because it determines the return value from the EqualBuffer method. If cleared using the string SqlTimestamp, the method always forces an update, even when the user just looked at the record and then clicked Ok instead of Cancel.

These frequent updates also forced a change to the LastModifiedTimestamp column by the server. With a small number of test records and multiple users, we were therefore seeing unexpected Changed By Another errors.

In regard to NOWHERE, would it not be wise to avoid use IF a timestamp column has even a slight chance of being relevant to real changes by another station?