0

I wrote a copybook (/COPY) procedure that has this interface:

DCL-PI *N VARCHAR(5000);
  FILE_NAME CHAR(10) CONST;
  DS_OLD VARCHAR(5000) CONST;
  DS_NEW VARCHAR(5000) CONST;
END-PI; 

This procedure is called by this sample program. FILE_DS_* are external DS with PFFILE definition.

EXEC SQL SELECT * INTO :FILE_DS_OLD FROM PFFILE FETCH FIRST 1 ROW ONLY;

FILE_DS_NEW = FILE_DS_OLD;
FILE_DS_NEW.MYFIELD = 'MODIFIED';

RESULT = MYPROC('PFFILE':FILE_DS_OLD:FILE_DS_NEW);

The field I'm modifying is defined as VARCHAR and its original value is, for example:

'PEN IS ON THE TABLE'

Strange thing is that at the entry point of the procedure I've got this value on the FILE_DS_NEW DS:

'MODIFIEDN THE TABLE'

I went mad but couldn't find why! Any idea?

How DS are defined:

D FILE_DS_OLD   E DS                  EXTNAME(PFFILE) QUALIFIED INZ
D FILE_DS_NEW   E DS                  EXTNAME(PFFILE) QUALIFIED INZ
LppEdd
  • 20,274
  • 11
  • 84
  • 139
  • show the DS definitions – Charles Nov 11 '16 at 20:46
  • @Charles They just shutted down the system. I'll add it tomorrow morning! Have you got any clue? The field in question should be defined as character with VARYING keyword. It's a DDS physical file, no SQL: – LppEdd Nov 11 '16 at 21:03
  • @Charles If you meant the local data structures, I added the definition. – LppEdd Nov 11 '16 at 21:12
  • If MYFIELD is varchar, are there two bytes just before the actual value with the length to use? If so, it might be fine that you see left-over stuff in the memory location of the field. RPG should only use up to the length specified in those first two bytes. – Tracy Probst Nov 12 '16 at 19:11
  • @TracyProbst exactly! MYFIELD is 256 byte but true length is 258. Problem is I need to get the field from the entry string by doing a "substring" (I get the file definition by looking at SYSCOLUMNS and then I split the big string in small pieces) Basically I'd have to look at the first two bytes and use that value as the substring length. – LppEdd Nov 12 '16 at 19:27
  • It would help to see the DDS....also is this the actual code? Or a simple example? What you're saying is happening doesn't make sense given the code if MYFIELD really is 256. – Charles Nov 14 '16 at 14:28
  • 1
    @LppEdd that's exactly right. If you are figuring the value via substring then you must look at the first two bytes to get the "true" length. If you can post some actual code with the field defs in both programs, I can try to craft an appropriate answer. – Tracy Probst Nov 14 '16 at 14:33
  • @TracyProbst done already! But thanks a lot! I had to "unpack" the value of the two bytes. – LppEdd Nov 14 '16 at 14:44
  • @Charles Tracy is right. I just had to look at the first two bytes and there i found the actual length. It's not the actual code, just an example of the problem – LppEdd Nov 14 '16 at 14:46

1 Answers1

0
FILE_DS_NEW = FILE_DS_OLD;   (1)
FILE_DS_NEW.MYFIELD = 'MODIFIED';  (2)
  1. You're moving all ds-data from old to new ds.
  2. You're setting a subfield of the new ds. I bet you myfield is char(8), so you're just changing the first 8 bytes of the new ds.

I'm guessing you're confused about the varchar. Varchar data type is just a way to save data just to the limit of the field. This means if you have a varchar(10) and just 'DATA' this field is using only 6 bytes. If you change it to varchar(1000) the field will be still using just 6 bytes.

I hope this helps.

Jairo R. Flores
  • 724
  • 4
  • 11
  • DSPFFD shows MYFIELD length is 256 bytes, and it is a variable length field. So, how do I change the entire value of the field with "MODIFIED"? I even tried clearing the field before. – LppEdd Nov 12 '16 at 15:28
  • Why clear the `entire value` of a VARCHAR field? The `entire value` is only as much as the current length. Clearing any more than that just wastes processor time and effectively removes any value of making the field VARCHAR instead of CHAR. – user2338816 Nov 21 '16 at 22:03