Skip to main content

Create/Write Data to IFS file from SQL - IBM i

IFS Stream File

IFS (Integrated File System) stream files are major part of any (or most of) IBM i applications. 

There are various ways to create stream files like CPYFRMIMPF, CPYFRMSTMF, EDTF...

Creating the IFS file and writing the data has been made much easier with SQL procedure IFS_WRITE (IFS_WRITE_BINARY for writing the data in Binary format and IFS_WRITE_UTF8 for writing the data in UTF8 format). 

In this post, we will see how to write the data into Stream file directly from SQL using IFS_WRITE procedure. 

E.g.: 

To start with, What we need is 'Path Name (IFS Directory & File Name)' and 'Data to be written'. 

Write data into IFS file from SQL on IBM i

  • First parameter 'PATH_NAME' accepts the IFS path name along with the file name.
    • In this example, '/home/REDDYP' is the directory and 'NewTextFile.txt' is the file name. 
    • Directory should be present by the time the procedure is called. If not, Procedure call would be failed. 
    • File name doesn't necessarily need to be present. If the is not present, File would be created. If already present, Data will appended to the file by default.
  • Second parameter 'LINE' accepts the data that is to be written into the file. 
In this example, file 'NewTextFile.txt' isn't already present. So, the file is created once the procedure is run. 

Write data into IFS file from SQL on IBM i

This looks fine when we look at the file from 5250 session. But, if we download the file and open in the Text editor, it appears like the below.

Write data into IFS file from SQL on IBM i

The reason behind this is CCSID used. By default IFS_WRITE creates the file with Job's default CCSID. If we need the file to be created with specific CCSID, we need to pass this using 'FILE_CCSID' parameter. 

Write data into IFS file from SQL on IBM i

  • Parameter 'FILE_CCSID' accepts an integer value (CCSID) and will be used to create the stream file.
    • This is only used when creating the new stream file and has no effect if the file is already present. 
    • Default value for this parameter is '0' for IFS_WRITE. File will be created with Job's CCSID if '0' is specified (or default).
    • Default value for this parameter is '1208' for IFS_WRITE_UTF8 and '0' for IFS_WRITE_BINARY.
Write data into IFS file from SQL on IBM i

This looks fine from 5250 session, let's see how this would look like if we download the file. 

Write data into IFS file from SQL on IBM i

So, If we need to create the file with the data (and replace if the file already exist), we can make use of the parameter 'OVERWRITE'. 

Write data into IFS file from SQL on IBM i

  • Parameter 'OVERWRITE' determines how the data passed (in LINE parameter) to be added to the file. Below are the valid values for this parameter.
    • APPEND - This is the default value for this parameter. Data is appended if the file already exist and File would be created if not already exist.
    • REPLACE - Replace the data in the existing stream file with the data passed. If file isn't already exist, file would be created. 
    • NONE - This is to be used if the new file needs to be created always. Procedure will fail if the file already present and new file would be created if the file is not present.

Write data into IFS file from SQL on IBM i

Passing 'APPEND' parameter or not passing this parameter would append the data to the file.

Write data into IFS file from SQL on IBM i

In the above example, New line has been written with the data passed. If we need to append the data on to the same line rather than creating new line, we can make use of 'END_OF_LINE' parameter. However, this parameter needs to be used for the line which needs data is added on to (rather than in the query that needs to be added). 

E.g.: 

If the data needs to be appended to Third Record, END_OF_LINE parameter needs to be passed with 'NONE' while writing this record. So that following line can be appended to the same record. 

Write data into IFS file from SQL on IBM i

  • Parameter 'END_OF_LINE' determines what needs to be written at the end of the line. Below are the valid values for this parameter.
    • CRLF - This is the default value for IFS_WRITE (and IFS_WRITE_UTF8). Carriage return and Line feed are appended to the end of the line.
    • CR - Carriage return is appended to the end of the line.
    • LFCR - Line feed and Carriage return are appended to the end of the line. 
    • LF - Line feed is appended to the end of the line.
    • NONE - No end of the line characters are appended i.e., Data appended will be added to the same record. This is the default value for IFS_WRITE_BINARY.
Write data into IFS file from SQL - IBM i

When the IFS_WRITE is called next time data is appended to the same line. 

Write data into IFS file from SQL on IBM i

Below is the Syntax of this procedure with all the parameters. 

CALL QSYS2/IFS_WRITE
     (PATH_NAME => 'IFS Path with directory and File Name', 
      LINE => 'Data to be written',
      FILE_CCSID => CCSID(Integer),
      OVERWRITE => 'Overwrite Option',
      END_OF_LINE => 'End of Line Option') 

All the above examples showing the data line by line into the file. Let's see how we can write the data from a file into the Stream file using IFS_WRITE. This would a bit of coding in SQL. 

Write data into IFS file from SQL on IBM i

In the above query, we are calling IFS_WRITE twice. Once to create the empty file (or replace with blank if file is already present) and Second time, it is called inside FOR loop to write each line from Table. Let's see each of the parameter in detail.

  • Line - 4: Parameter 'LINE' with no data is to create the blank file. Next time IFS_WRITE is called is in the loop, so it is better to create the blank file first and append the data. 
  • Line - 5: Parameter 'OVERWRITE' with 'REPLACE', This is to replace any data in the current file if the file is already present. 
  • Line - 6: Parameter 'END_OF_LINE' with 'NONE', This is to append the data from the first line.
  • Line - 9: FOR loop with SELECT query of table 'REDDYP1/IFSFILE'.
  • Line - 10: IFS_WRITE with data to be written. This procedure is called for each row in the table and the data is added to the new row (with default value on OVERWRITE).
IFS_WRITE_BINARY and IFS_WRITE_UTF8 works in the same way only difference is data to be passed in Binary and UTF8 formats respectively. 


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

Comments

Popular posts from this blog

All about READ in RPGLE & Why we use it with SETLL/SETGT?

READ READ is one of the most used Opcodes in RPGLE. As the name suggests main purpose of this Opcode is to read a record from Database file. What are the different READ Opcodes? To list, Below are the five Opcodes.  READ - Read a Record READC - Read Next Changed Record READE - Read Equal Key Record READP - Read Prior Record READPE - Read Prior Equal Record We will see more about each of these later in this article. Before that, We will see a bit about SETLL/SETGT .  SETLL (Set Lower Limit) SETLL accepts Key Fields or Relative Record Number (RRN) as Search Arguments and positions the file at the Corresponding Record (or Next Record if exact match isn't found).  SETGT (Set Greater Than) SETGT accepts Key Fields or Relative Record Number (RRN) as Search Arguments and positions the file at the Next Record (Greater Than the Key value). Syntax: SETLL SEARCH-ARGUMENTS/KEYFIELDS FILENAME SETGT  SEARCH-ARGUMENTS/KEYFIELDS FILENAME One of the below can be passed as Search Arguments. Key Fiel

What we need to know about CHAIN (RPGLE) & How is it different from READ?

CHAIN READ & CHAIN, These are one of the most used (& useful) Opcodes by any RPG developer. These Opcodes are used to read a record from file. So, What's the difference between CHAIN & READ?   CHAIN operation retrieves a record based on the Key specified. It's more like Retrieving Random record from a Database file based on the Key fields.  READ operation reads the record currently pointed to from a Database file. There are multiple Opcodes that start with READ and all are used to read a record but with slight difference. We will see more about different Opcodes and How they are different from each other (and CHAIN) in another article. Few differences to note.  CHAIN requires Key fields to read a record where as READ would read the record currently pointed to (SETLL or SETGT are used to point a Record).  If there are multiple records with the same Key data, CHAIN would return the same record every time. READE can be used to read all the records with the specified Ke

Extract a portion of a Date/Time/Timestamp in RPGLE - IBM i

%SUBDT Extracting Year, Month, Day, Hour, Minutes, Seconds or Milli seconds of a given Date/Time/Timestamp is required most of the times.  This can be extracted easily by using %SUBDT. BIF name looks more similar to %SUBST which is used to extract a portion of string by passing from and two positions of the original string. Instead, We would need to pass a value (i.e., Date, Time or Timestamp ) and Unit (i.e., *YEARS, *MONTHS, *DAYS, *HOURS, *MINUTES, *SECONDS or *MSECONDS) to %SUBDT.  Valid unit should be passed for the type of the value passed. Below are the valid values for each type. Date - *DAYS, *MONTHS, *YEARS Time - *HOURS, *MINUTES, *SECONDS Timestamp - *DAYS, *MONTHS, *YEARS, *HOURS, *MINUTES, *SECONDS, *MSECONDS Syntax: %SUBDT(value : unit { : digits { : decpos} }) Value and Unit are the mandatory arguments.  Digits and Decimal positions are optional and can only be used with *SECONDS for Timestamp. We can either pass the full form for the unit or use the short form. Below i