Help - Adabas Natural Tecnical Test (Interview)

Can someone send some exercises to help my study for an interview please?

At my former company (not in the UK) I developed a technical test for applicants. I’m not able (and maybe not allowed) to publish the whole test here.

One of the exercises was, to fix a bug in an existing Natural-Program. The program was stowable, but it got a NAT3047 during execution. The program code was like this:

define data
01 view-1 view of file1
  02 field1
  02 field2
end-define
read view-1 by field1
  if view-1.field2 = 'XY'
     move 'AB' to view-1.field2
     update
  end-if
end-read
end transaction
end

Could you send it for my e-mail?

Code:
define data
01 view-1 view of file1
02 field1
02 field2
01 #CNT (n03)
end-define
read view-1 by field1
if view-1.field2 = ‘XY’
add 1 to #cnt
move ‘AB’ to view-1.field2
update
end-if
if #cnt eq 50
end-transaction
reset #cnt
end-if
end-read
end transaction
end

Is it ok?

I need more! thanks!
ehheeh

No! Your code would still produce a NAT3047.

read view-1 by field1
*
add 1 to #cnt
*
if view-1.field2 = ‘XY’
move ‘AB’ to view-1.field2
update
end-if
*
if #cnt eq 50
end-transaction
reset #cnt
end-if
*
end-read
end transaction
end

Now! Is it ok?

If not please explain ! :slight_smile:

Could give me a hand and send some exercises with resolutions please?

Thank You

Okay, you avoided the 3047.

HOWEVER, depending on the number of records in the file, and the number of records with XY, you might instead wish to:

if view-1.field2 = ‘XY’
getr. GET VIEW-2 *ISN
move ‘AB’ to view-2.field2
update (getr.)
end-if

you could also reduce view-1 to just field2 and have all the other fields you might need for the update in view-2.

steve

Thanks Steve.

That’s was great.

Your code would work, but it’s much better to use Steve Robinson’s solution.

As I mentioned above, I’m not in the company any more (where I developed the test). So I write one exercise from memory. That’s all I can do at the moment.

BTW: With that exercise you can see, if the programmer knows some important Natural/Adabas-Internals about Transaction processing (i.e. Hold-queue-logic, GET Statement)

Before attempting a solution to the 3047 error, I would first as a few questions:

  1. How often does this process run?
  2. How many records are on the file?
  3. How many records do we expect to update?

If it is a one time or twice a year sweep, then efficiency isn’t much of a concern. If it runs daily and we are only updating a small percentage of the file, I would consider making FIELD2 a descriptor.

If making FIELD2 a descriptor is out of the question, then what do you think of this?

define data local
  01 view-1 view of file1
    02 field2
  01 view-2 view of file1
    02 field2
  01 #et-ctr (n3)
  01 #isn     (n10)
end-define
*
read view-1 by field1
  if view-1.field2 ne 'XY'
    escape top
  end-if
  move *ISN to #isn
end-all
sort by view-1.field2  using #isn
  add 1 to #et-ctr
  gt. 
  get view-2 #isn
  move 'AB' to view-2.field2
  update (gt.)
  if #et-ctr gt 50
    end transaction
    reset #et-ctr
  end-if
end-sort
*
end transaction
*
end

The GET makes sure you are only holding records you intend to update. The sort gathers all the records to be updated together so you minimize the number of ETs being executed.

An interesting idea (minimizing ETs), but an expensive way to do it. The SORT is totally unnecessary; indeed, it is not doing anything :slight_smile:

If you want to do this, have an array for the ISNs. The code would be something like:

read view-1 by field1
if view-1.field2 ne ‘XY’
escape top
end-if
ADD 1 TO #COUNT
move *ISN to #isn (#COUNT)
end-read
*
for #loop = 1 to #count
gt.
get view-2 #isn (#loop)
update (gt.)
etc.

you would need a counter to 50 in the FOR loop which would control an ET statement.

steve

I’m not sure, but I think NISNHQ was set to 3,000. The file contained more than 100,000 records. And 1% of the records should be updated.

To be honest: I don’t understand what the advantage of the SORT should be. Even if you collect the ISNs in an ARRAY: This doesn’t save ETs from my point of view.
So I think the best way is to use the GET-Statement and a transaction counter.

@watty: Good luck!

Hi Matthias;

With the numbers cited above, you are probably right about not saving much by using an ISN array, however, consider a slightly (okay, a bit more than slightly) changed scenario:

I have a file with 10 million records, 100,000 will be updated. HOWEVER, all records will also be processed, and the processing may involve a bit of work per record.

Using the GET, as I wrote earlier, would involve 100,000 ETs. The reason is not to avoid record hold queue problems, but (potentially) to avoid an ET timeout. Hence, every UPDATE would be followed by an ET.

Now consider building an array of ISNs for UPDATE (agreed, the SORT is not necessary). I do my non-update (and potentially time consuming) processing in the READ loop where I do not have to be concerned with timeouts.

Now, I can process the array of ISNs. Without anything else going on except a FOR loop with a GET and an UPDATE, I could probably issue an ET every 50 or 100 or even 1000 records and still be quite safe from a record hold or an et timeout problem. If we could actually go with a counter of 1000, we reduce the number of ETs from 100,000 to 1,000, thus saving 99,000 ETs, a considerable number for a very simple code change.

steve

The one advantage I saw in using the sort over an array is I didn’t know how many records would be updated. There is no guarantee that any dimension I put on the array will be large enough. SORT does not have that limitation, albeit at some cost in overhead.

One way around the array limitation is to define your array with 1000 occurences and process it when the array is full:

read view1 by field1
   if view1.field2 ne 'XY'
      escape top
   end-if
*
   add 1 to #i
   move *isn to #isn(#I)
   if #i = 1000
      perform update-isn-list
      reset #i #isn(*)
   end-if
end-read

Now, if I were going to follow my shop standards, I would select the records to be updated in one program, write the ISN (or other unique key to the record), old value and new value for the field to a work file, then read that work file in a second program that does the updates.

That gives us a safety valve if something goes wrong to restore the records to their previous values.

And, in V 4.2, X-tensible arrays which would solve the problem of not knowing an explicit upper bound when the update program starts.

steve

And you can also do a semantically equivalent way with Nat 4.1 already: define an array of one million (or less :wink:) (A) dynamic elements. Store the values in this array. Only the needed occurrences will occupy space, the others are only defined. The overhead you have, is to have a redefined structure, move this structure to the array element (for storing values) and to move an array element to the structure (for reading).

OK. You’re right! This would avoid NAT3009 (Timeout) and maybe NAT3145 in concurrent dialogs (because the records are held for a shorter time).

To be really on the save side, you have to think about NAT3113. But I think that would go too far… :wink: