Solved

Reading variable length EBCDIC in SAS

Posted on 2016-08-24
9
78 Views
Last Modified: 2016-09-07
I am trying to read an incoming mainframe file that contains a variable length field that contains EBCDIC data.

To read this field, I am currently using $VARYING informat, but this is only suitable for reading variable length ASCII fields. What I am looking for is an informat that reads a variable length field AND converts to readable format in the output.

Here is my code :-

			/* P31 - NAME_LINE_1 */
			if Bitmap_1a='..............................1.'B then
			do;
				input
				b_ADDESS_LINE_1_len $370FIB2.
				b_ADDESS_LINE_1 $VARYING23. b_ADDESS_LINE_1_len
				@;
				data_length = data_length - b_NAME_LINE_1_len - 2;
			end;

Open in new window


The problem with the above code is that it populates the output with the EBCDIC, but I need the variable field converting to ASCII. Is there a way to convert a variable length field from EBCDIC to ASCII without relying on the informat / format statements?
0
Comment
Question by:Martin r
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 19

Expert Comment

by:Thommy
ID: 41768962
You should read the book Reading External Data Files Using SAS: Examples Handbook

Check the table of contents. There are a lot of examples including reading EBCDIC data...
0
 
LVL 19

Expert Comment

by:Thommy
ID: 41768989
And also check this from SAS Knowledge Base...
Reading EBCDIC Files on ASCII Systems
0
 

Author Comment

by:Martin r
ID: 41769050
Thanks for the comments Thommy, but I have already looked at the recommended documentation online, and this is really a last resort for me - as there is nothing anywhere that indicates SAS is actually capable of reading variable length EBCDIC informats. In fact, I don't think it is....:-|

I have no difficulty reading  fixed-length EBCDIC fields, as well as the binary fields that specify the record-length and segment-length - this is all working. It's just there is no INFORMAT that will allow me to read and convert EBCDIC to ASCII for a variable length field.

I did just have a thought though - I could read the field as "FIXED EBCDIC" and then reset the pointer back to the correct position according to the value of the b_ADDESS_LINE_1_len field. It would only be a simple matter of chopping the surplus data from the end of the field.
0
 
LVL 8

Accepted Solution

by:
ShannonEE earned 500 total points
ID: 41774240
Even better would be -

		/* P31 - NAME_LINE_1 */
			if Bitmap_1a='..............................1.'B then
			do;
				input
				b_ADDESS_LINE_1_len $370FIB2.
				b_ADDESS_LINE_EBCDIC $VARYING23. b_ADDESS_LINE_1_len
				@;
				data_length = data_length - b_NAME_LINE_1_len - 2;
				b_ADDESS_LINE_1 = inputc(b_ADDRESS_LINE_EBCDIC,  $EBCDIC. b_ADDRESS_LINE_1_len);
			end;

Open in new window


Note that you need to specify both a type ( $ ) and max width for both

b_ADDESS_LINE_1  and
b_ADDRESS_LINE_EBCDIC

Failure to specify a width can lead to very mysterious run time problems.

Maybe that max length is 23 as you have on the $VARYING informat, but it is best also to have a statement

length   b_ADDESS_LINE_1  b_ADDRESS_LINE_EBCDIC $ 23;

Open in new window


This does the varying field length issue in the input statement and then uses the INPUTC function to do the conversion from EBCDIC.

Regards,

Ian
1
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 16

Expert Comment

by:theo kouwenhoven
ID: 41785907
Hi Martin,

I don't know if this will help, but normally the Ebcdic to Ascii translation will be automatically don by the DB-driver, unless it's Binary-data (Bitmap).
The Varlength fields in a DB2 database has the first 2-positions filled with the length of the data.
0
 

Author Closing Comment

by:Martin r
ID: 41786506
Thanks ShannonEE!

The solution is exactly what I was after. The solution ShannonEE provided is for RUNTIME FUNCTION to allow conversion during the loop.

http://support.sas.com/kb/50/013.html

I have managed to convert the variable length field now so can ensure the output is all formatted in ASCII. The final code was as follows :-

                  /* P31 - REFERENCIA DEL ADQUIRENTE */
                  if Bitmap_1a='..............................1.'B then
                  do;
                        input
                        b_acquirer_reference_len $EBCDIC2.
                        b_acquirer_reference_ebcdic $VARYING23. b_acquirer_reference_len
                        @;
                        data_length = data_length - b_acquirer_reference_len - 2;
                        b_acquirer_reference_ascii = inputc(b_acquirer_reference_ebcdic, "$EBCDIC23.");
                  end;

Thanks all for your help!!
0
 

Author Comment

by:Martin r
ID: 41786528
****UPDATED****

The above solution worked, but produced excessive notes due to specifying the maximum length for format. Therefore I used a concatenation to enable the length variable to be used in the format construction. The final code was as follows :-

                  /* P31 - REFERENCIA DEL ADQUIRENTE */
                  if Bitmap_1a='..............................1.'B then
                  do;
                        length b_acquirer_reference_ebcdic b_acquirer_reference_ascii $ 23;
                        input
                        b_acquirer_reference_len $EBCDIC2.
                        b_acquirer_reference_ebcdic $VARYING23. b_acquirer_reference_len
                        @;
                        data_length = data_length - b_acquirer_reference_len - 2;
                        b_acquirer_reference_ascii = inputc(b_acquirer_reference_ebcdic, "$EBCDIC" || b_acquirer_reference_len || "." );
                  end;
0
 
LVL 8

Expert Comment

by:ShannonEE
ID: 41787032
Martinr,

The posted code missed a comma.  With the INPUTC  function sas makes the format up at run time (which you did), but if you specify the 3rd parameter (which I attempted to do) then it should construct the format without any NOTES or WARNINGS.  As in

		b_ADDESS_LINE_1 = inputc(b_ADDRESS_LINE_EBCDIC,  $EBCDIC.   ,   b_ADDRESS_LINE_1_len);

Open in new window


(A comma after $EBCDIC and before b_ADDRESS_LINE_1_LEN  was missing)
I didn't test out the code because currently I don't have access to a mainframe to write test data and the code is quite specific to your situation.

As an aside, note that on the mainframe the record format and length is specified in the DCB and (from what I remember) includes F, FB, V, VB, VBA, D, DB, U, (and probably a host of other formats).  Obtaining the record length will be different for each record format.

In your case it appears that the field length is in another field within the record and so getting the record length from the data structure as read in an ASCII environment will be useless for inputting the variable length field that you need to do here.
1
 

Author Comment

by:Martin r
ID: 41787331
Thanks ShannonEE, that's a neater expression. I should point out that I am using SAS Enterprise Guide (Windows) - hence requiring the output in ASCII; so I have to specify the format in quotes.

/* P31 - REFERENCIA DEL ADQUIRENTE */
if Bitmap_1a='..............................1.'B then
do;
	length b_acquirer_reference_ebcdic b_acquirer_reference_ascii $ 23;
	input
	b_acquirer_reference_len $EBCDIC2.
	b_acquirer_reference_ebcdic $VARYING23. b_acquirer_reference_len
	@;
	data_length = data_length - b_acquirer_reference_len - 2;
	b_acquirer_reference_ascii = inputc(b_acquirer_reference_ebcdic, "$EBCDIC." , b_acquirer_reference_len);
end;

Open in new window

0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Need help editing script 3 53
strings to secure devices 8 40
Linux Scripting 3 56
Car computer reset 4 52
EE introduced a new rating method known as Level, which displays in your avatar as LVL. The new Level is a numeric ranking that is based on your Points. This article discusses the rationale behind the new method and provides the mathematical formula…
This story has been written with permission from the scammed victim, a valued client of mine – identity protected by request.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Where to go on the main page to find the job listings. How to apply to a job that you are interested in from the list that is featured on our Careers page.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now