Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Reading variable length EBCDIC in SAS

Posted on 2016-08-24
9
Medium Priority
?
267 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 
LVL 8

Accepted Solution

by:
ShannonEE earned 2000 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
 
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

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Finding a job can be stressful - searches, resume tweaks, and networking events can be super boring. Luckily we're here to help you land your dream job!
We live in a world of interfaces like the one in the title picture. VBA also allows to use interfaces which offers a lot of possibilities. This article describes how to use interfaces in VBA and how to work around their bugs.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

636 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