Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File Status 22: which key?

Status
Not open for further replies.

theotyflos

Programmer
Oct 15, 2000
132
GR
Hi group,

Language is RM/Cobol v9 on windows.
A have an indexed file with 2 NON duplicate keys (the primary and an alternate) like the following:
Code:
       File-Control.
           Select Optional             Some-File
                  Assign To Random     Some-Path
                  Organization Indexed Access Dynamic
                  Record Key           Some-Key
                  Alternate Record Key Some-Alt-Key
                  File Status          Some-Flst.
           :
       File Section.
       FD  Some-File.
       1   Some-Rec.
           2   Some-Key            Pic Something.
           2   Some-Alt-Key        Pic Something-Else.
           2   Some-Data           Pic Something-Other.

Trying to write a record that already exists, I get a file status "22" (duplicate key); that's ok so far. BUT, I don't know which key is duplicate. C$RERR doesn't give any further info. Is there any way to know which one of the 2 keys (or both maybe) is duplicate?

Thanks in Advance.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
Theophilos,

There is no means to determine this from the status, but the information can be obtained as follows:
Code:
WRITE Some-Rec FROM WS-Rec
  INVALID KEY
    IF Some-Flst = "22"
      READ Some-File KEY Some-Key
        INVALID KEY
          DISPLAY "Duplicate Alternate"
        NOT INVALID KEY
          DISPLAY "Duplicate Primary"
      END-READ
    END-IF
END-WRITE
Perhaps this is adequate?

Tom Morrison
 
Tom,

Thank you for your reply. The solution that you propose, is surely satisfactory, even if I would prefer a more "direct" approach (thru file status). Is there any chance, that such a solution (via file status or C$RERR) will be supported in the futute?

Thanks again.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
I think I can enter an enhancement request. However, please use the Online Support Request here since I am unable to respond to indirect requests made on forums and newsgroups.


BTW, one thing has changed since 2003: I am now the Manager of Technical Support and Services.

Tom Morrison
 
Thanks again Tom. My congratulations and my best wishes for your promotion.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
Theotyflos

Although it is feasible to do that from a technical point of view, I wonder whether performance wise that would not cause a problem, or if that would be surpassed for the possible benefit of knowing which key(s) are breaking the constraint.

I do now know how the RM filemanager is handling indexed key verification, but I would expect it to "fail" on the first duplicate error found.

So supposing that you have a indexed file with 30 alternate keys, all with no duplicates allowed, what do you think the filemanager should do?

Should it report all keys?
If so then when the first duplicate is found the filemanager will perform further index searches (without updates at this stage, as an error has already been found), and this will obviously impact performance.
Furthermore it will imply that either a variable big enough to contain a indicator for each possible alternate key (255 on RM) is made available, or you will need to perform successful calls to C$CERR until you have found all keys in error.

Or should it report just the first one?
If this is the case, and if you "fix" that data, you still don't know if the other keys will fail on the subsequent update so this probably won't help you either.


Just some thoughts on this subject.



Regards

Frederico Fonseca
SysSoft Integrated Ltd
 
With Dynamic access arent you having to use the Start command first?

How is the file Opened?
Open I-O
Open Output

If you used a start command you would know if there was a record key matching. The start command would fail with an invalid File Status. If you read the file first you would know if it was a duplicate.

Read the file First.

invalid read go to or perform write routine
Add one to ws-write
valid read go to or perform rewrite routine
add one to ws-rewite
display results at EOJ

On a new file you have to write a record first so there is something there. You can write a simple program to do write and then delete to initialize the file or write one header record you always bypass.

If you do not like my post feel free to point out your opinion or my errors.
 
ceh4702

START not necessary. DYNAMIC access is exactly the type of access that requires the programmer to distinguish between READ and READ...NEXT.

The point of the original poster was that he already knows (by the INVALID KEY and FILE STATUS = "22") that he has a duplicate key value. His problem was, "Which key?"

Indeed if the file is OPEN ... OUTPUT then my suggestion will not work. In practice there are not too many times that one opens a file OUTPUT (it does nicely remove all those unseemly records you might have hanging around, though).

Frederico, your points are quite correct (as usual). I am not sure our file manager can really provide meaningful results in the presence of multiple keys having duplicate values, since we indeed would stop after discovering the first one.

Tom Morrison
 
Frederico,
Your thoughts are very wise. I really don't know which method (report only the first or all duplicate keys) is the more appropriate. Maybe it depends on the "nature" of each situation. Concerning the current problem I'm facing, it is enough just to report the first duplicate key, but it may not be enough for other situations. Right now I can't imagine of such one, but maybe there are other programmers who are having a similar problem (I programm in Cobol since 1987 and this is the first time I need such an information).

For the history, please allow me to report the actual problem:

A customer needs (demands actually[mad]) to be able to change the item's main code (which is/was the primary key) any time he wishes.
Of course, the item's code is part of primary or alternate keys in a lot of other files (invoices etc.).
So, normally, when the customer wishes to change the item's code, I would have to scan all of these files and change the code there also.
Instead of doing this, I figured an alternate solution: Change the item's code from primary to alternate with no duplicates, put another field in the item's master file as the primary key (which would act like an autoincrement field) and use this new field as a "link" between the master file and the rest. (By the way, I made this new primary key autoincrement and invisible to the customer. If I made it user-insertable he would just shoot me).
This way, when the customer changes the item's "master code", I only have to rewrite the master file (Comments/thoughts on this technique are more than welcome).
The problem occurs when the customer wants to enter a brand new item: At that time I come in need of knowing which key is duplicate. My intention is, if the (now alternate) "master item code" is duplicate, just inform the user that the item already exists and ask for an other code. If instead the (new autoincremented) primary key is duplicate, I just increment it and try to write again the record.

(I hope my english is good enough to make all this mess clear to you).

ceh4702,
I appreciate your posting, though I think you missed the point. My problem is not how to handle a duplicate record condition, but to know which key is duplicate. Thanks anyway.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
And isn't the code posted by Tom (k5tm) a good starting point ?
You may also consider doing some sanity checks before attempting the WRITE.

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
PHV,
PHV said:
And isn't the code posted by Tom (k5tm) a good starting point ?
It sure is (as i stated in my answer to him), I was just wishing for a more direct solution.
PHV said:
You may also consider doing some sanity checks before attempting the WRITE.
Well, I think that sanity checks before the WRITE aren't enough in a multiuser environment, since there is a time window between the check and the actual WRITE.
On a second thought, there may be also a "multiuser" issue with Tom's solution; not sure enough, have to check it.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
I think your problem is on how you are allowing the user to enter a new record.


In this type of application the user can only do the following operations

Create
Delete
Update


All the above have one thing in common (or should have!!).
Before allowing the remaining of the operation to continue you need to verify if the "KEY" already exists.

If it does
On Create mode you show an error message and prevent the user to use that "KEY"
On Delete/Update modes the current record should be shown to user for further processing.

If Doesn't
On Create mode you should present the user with a blank record (and eventually with the "KEY" field protected.)
On Delete/Update modes a message should be sent to user (Item does not exist)

All the above imply a READ KEY IS MY_ALTERNATE_UNIQUE_KEY done at the beginning of the operation.

At this stage you have part of your problems solved.
If all these modes you know that the real primary key will NEVER issue a duplicate error if you issue an write/rewrite/delete.
This assumes that your primary key is based on another table/file that holds the sequence number to use. (this should be a read (numbering_file) with lock, add increment_value, rewrite, done on a loop should the read encounter a lock by another user. Loop done just a few times to allow for the record to be released by the other users, and only at the final stage of your create mode operation).

If you are not using a different file, but you are just using a loop write/increment/write until successful, then you should rethink this process.

So the only problem you should have is when two users try to create/update a item with/to the same "KEY".
This may issue an invalid key, but as you know it can only be that particular field so you inform the user that the record already exists. What you do then depends on how your application works. If you have a CREATE and/or MODIFY timestamp you can give that information to the user.


Hope the following is of some help.


Regards

Frederico Fonseca
SysSoft Integrated Ltd
 
Frederico,
Down to your quote
If all these modes you know that the real primary key will NEVER issue a duplicate error if you issue an write/rewrite/delete.
I agree 100% with you.
Regarding the separate file for holding the sequence number, I don't quite like it, first because of the extra overhead (updating 2 files instead od one) and second because a lot of things could go wrong between the "get the sequence number" and "update the master file". I used this technique some years ago but I've abandonded it since.
I came at another solution which doesn't need an extra file and also handles the multiuser issue:
Code:
      *>   Actual Record to be written is in Wrk-Items-Rec.
      *>   Get the last AutoIncrement number
      *    Start    Items-Fil Key Is Last Itm-AutoIncrement
      *    Invalid         *> No records in file yet
      *      Move   0      To Itm-AutoIncrement
      *    NOT      Invalid
      *      Read   Items-Fil Previous
      *      At End        *> Someone has just deleted the one and only record
      *        Move 0      To Itm-AutoIncrement
      *      End-Read
      *    End-Start
      *
      *>   Here we have the last AutoIncrement in the file so we can
      *>   compute the next available. Record is still locked so
      *>   nobody can steal our AutoIncrement
      *    Add      1      To Itm-AutoIncrement
      *                Giving Wrk-Itm-AutoIncrement
      *
      *>   Transfer work-area to actual record and write
      *    Move     Wrk-Items-Rec  To Items-Rec
      *    Write    Items-Rec Invalid
      *      If     Itm-File-Status = "22"
      *>       At this point, "22" can be only for the Item's Code
      *>       so report to user that item code exists
      *      Else
      *>       Something went terribly wrong
      *      End-If
      *    End-Write
      *    Unlock   Items-Fil

I'm not absolutely sure that it works yet. I'll check it and post the results.

Thank you very much for your valuable thoughts.

Regards.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
oops!!! sorry for all the "*"s.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
[banghead]

It does NOT work if there are no records in the file and some other process writes a record between this process's "end-start" and "write": Both processes will get an AutoIncrement of 1. [hairpull]

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
Theotyflos

Using another file for the process only introduces an extra step for open/close the file.

And has all the benefits of allowing you to use that file for ALL types of numbering if you add a "PROCESS TYPE" as part of the key.

As for something going wrong from getting this sequence, and updating the real file, it is true it can happen, but it can happen anyway in other situations.

What do you do if you are updating a invoice line file and it "breaks" in the middle of writing the invoice lines? this is the problem you can have with RM/COBOL, and whatever solution you have for this case is what you should apply for the numbering IF the correct sequence is a MUST. On this particular process having a correct sequence (e.g. no missing sequence numbers) is NOT important as far as I can see.



Regards

Frederico Fonseca
SysSoft Integrated Ltd
 
Hi
1. open file i-o. (if output, open f output, close f, open i-o f)
2. read main key ---> invlid msg
3. read first-alt key ----> invalid msg
4... rean n-alt key..s -----> invalid msg
5. write f-rec ----> invalid "abnormal msg".

From the first read until writing the record, the record is locked in any systems.

I think that is the regular & simple way to know the duplicate key.

COBOL is for ppl that want a simple code for farther maintenance & not too much smart, that is C lang. job...

Baruch
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top