This document actually contains 3 source files:

-        IMP_MRP4R The Raw data input

-        IMP_MRP4P The Processed ouput

-        PARSE_MRP4 The Stored Procedure which actually does the parsing job.

 

This is a simple parsing routine, which shows how a procedure allows one to use

two cursors, operating one within the other.

-        One cursor is used to read each row

-        One cursor is used to break apart each row content, splitting it into separate

output rows.

 

 

--------------------------------------------------------------------------------

--

-- Input table, containing text data. Each description is split with a "~"

-- character. This was used so that the table could be easily FTP-ed to

-- the iSeries without causing new records each time a carriage return was

-- found. The idea is to split each of these "sentences" and to create a new

-- record with the original material number found at the beginning of each

-- row.

--------------------------------------------------------------------------------

--/////////////////////////////////////////////////////////////////////////////

--------------------------------------------------------------------------------

--

-- Input table to contain un-parsed data

-- In this case, the data was originally in an XL table, it was then modified

-- to change the manual line feeds an replace them with ~ characters, so that

-- they would not affect the FTP process (see text further down).

--

--------------------------------------------------------------------------------

 

CREATE TABLE IMP_MRP4P

(

MATERIAL_NUMBER FOR HD_DT INT WITH DEFAULT 0 ,

TEXT_1 FOR PARSED1 CHAR(512)

) ;

 

--/////////////////////////////////////////////////////////////////////////////

--

-- Output table to contain descriptions, parsed from comma-delimited

-- IMP_MRP4R, now in table format.

--

--------------------------------------------------------------------------------

 

CREATE TABLE IMP_MRP4R

(

MATERIAL_NUMBER FOR HD_DT INT WITH DEFAULT 0 ,

TEXT_1 FOR ITMN1 CHAR(512) WITH DEFAULT ' ',

TEXT_2 FOR ITMN2 CHAR(512) WITH DEFAULT ' '

) ;

 

--/////////////////////////////////////////////////////////////////////////////

 

Here below is the stored procedure

 

--\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

-------------------------------------------------------------------------------

-- Name: PARSE_MRP4

-- Description: Stored procedure to read IMP_MRP4R and parse the

-- contents into a new table, IMP_MRP4P.

--

-- Author : Thibault Dambrine

-- Date : October 3, 2008

-------------------------------------------------------------------------------

--

-- IN: IMP_MRP4R (Raw MRP4 data)

-- OUT: IMP_MRP4P (Parsed MRP4 data)

--

-------------------------------------------------------------------------------

-- Notes: Prior steps in XL to re-format the tables sent by provider:

-- This is necessary to FTP the original data without unwanted

-- carriage returns, which cause FTP to create new records in

-- places where we really don't need them.

--

--

-- 1) Make a .csv copy of the original, leave only item number,

-- original description,

-- cleansed description

-- 2) Copy these three columns into a WORD document

-- 3) Global replace the manual line breaks (^l) with a squiggle (~) character

-- 4) Grab the Word document contents and re-insert into Excel

-- 5) Import into CAAS01

-- 6) Where Cleansed document = ' ', update with original

-- 'update EPBWIPMC2/IMP_MRP4R set text_2 = text_1 where text_2 = '' '' '

-- 7) Remove NULL values

-- 'delete from EPBWIPMC2/IMP_MRP4R where material_number is null '

--

-- In concrete terms, an XL set of cells looking like

-- ________________________________________________________________________________

-- |material_number | Description |

-- |_________________|_____________________________________________________________|

-- |1234567890 |Descriptor: middle bolt, rising stem ^l |

-- | |Diameter: 48 Inches ^l |

-- | |Connection ends: flange ^l |

-- | |Spec: (ASME/ANSI, B16.5A, ASME, B16.47), SW (ASME B16.25) ^l |

-- | |Operator: handwheel, gear, subulate gear, actuator ^l |

-- | |Sealing material: F6, F310, CoCrA, Cu, MoNCL ^l |

-- |_________________|_____________________________________________________________|

--

-- (note: the "^l" characters are not visible in XL - they

-- just trigger the carriage returns)

--

-- will enter as follows in an output table.

--

-- material_number Description

-- =============== ==========================================================

-- 1234567890 Descriptor: middle bolt, rising stem

-- 1234567890 Diameter: 48 Inches

-- 1234567890 Connection ends: flange

-- 1234567890 Spec: (ASME/ANSI, B16.5A, ASME, B16.47), SW (ASME B16.25)

-- 1234567890 Operator: handwheel, gear, subulate gear, actuator

-- 1234567890 Sealing material: F6, F310, CoCrA, Cu, MoNCL

--

--

--

-------------------------------------------------------------------------------

 

CREATE PROCEDURE PARSE_MRP4

 

LANGUAGE SQL

SET OPTION OUTPUT = *PRINT, DBGVIEW = *SOURCE

 

BEGIN

 

--------------------------------------------------------------------------------

-- Declare variables section --

--------------------------------------------------------------------------------

 

-- Declare string parsing Intake Variables

 

DECLARE W_MATERIAL_NUMBER INT ;

DECLARE W_TEXT_1 CHAR(512) ;

DECLARE W_TEXT_2 CHAR(512) ;

DECLARE W_NOTES_RRN INT ;

 

-- Declare string parsing Variables

DECLARE STRING_START INT DEFAULT 0 ;

DECLARE STRING_END INT DEFAULT 0 ;

DECLARE STRING_LENGTH INT DEFAULT 0 ;

DECLARE NEXT_START INT DEFAULT 0 ;

DECLARE END_OF_FILE INT DEFAULT 0 ;

DECLARE INNER_LOOP INT DEFAULT 0 ;

 

 

-- SQL System Monitoring Variables and work variables --

 

DECLARE SQLCAID CHAR(8) DEFAULT 'NO VALUE' ;

DECLARE SQLCABC INT DEFAULT 0 ;

DECLARE SQLCODE INT DEFAULT 0 ;

DECLARE SQLERRML SMALLINT DEFAULT 0 ;

DECLARE SQLERRMC CHAR(70) DEFAULT 'NO VALUE' ;

DECLARE SQLERRP CHAR(8) DEFAULT 'NO VALUE' ;

DECLARE SQLERRD CHAR(6) DEFAULT 'NO VAL' ;

DECLARE SQLWARN CHAR(11) DEFAULT 'NO VALUE' ;

DECLARE SQLSTATE CHAR(5) DEFAULT '00000' ;

 

 

-- SQL User Monitoring Variables and work variables --

 

 

--------------------------------------------------------------------------------

-- Declare Cursor to get the staging data one record at a time. --

--------------------------------------------------------------------------------

DECLARE CURSOR_01 CURSOR FOR

SELECT

notes.MATERIAL_NUMBER , -- Item Number

notes.TEXT_1 , -- Original Text

notes.TEXT_2 , -- Clean Text

rrn(notes) -- Original RRN

FROM

IMP_MRP4R NOTES ;

 

 

--------------------------------------------------------------------------------

-- This CONTINUE HANDLER is an equivalent to CPF0000. It absorbs the --

-- hard crashes in SQL, so that they can be handled with a monitor of --

-- SQLCODE instead. When bad data comes in, it is re-routed to CM999. --

-- A record of what has been done in this procedure will be recorded in --

-- CM997. --

--------------------------------------------------------------------------------

--XXXXXXX

-- DECLARE CONTINUE HANDLER FOR SQLEXCEPTION GET DIAGNOSTICS EXCEPTION 1

-- SQLERRMC = MESSAGE_TEXT ;

--XXXXXXX

--

-- note: in this program, this text was commented out because it was simply

-- not necessary. The data is simple, there are no unexpected cases.

--------------------------------------------------------------------------------

--CLEAR FILE IN ADVANCE

 

DELETE FROM IMP_MRP4P ;

 

UPDATE EPBWIPMC2/IMP_MRP4R SET TEXT_2 = TEXT_1 WHERE TEXT_2 = ' ' ;

 

DELETE FROM EPBWIPMC2/IMP_MRP4R WHERE MATERIAL_NUMBER IS NULL ;

DELETE FROM EPBWIPMC2/IMP_MRP4R WHERE TEXT_1 IS NULL ;

DELETE FROM EPBWIPMC2/IMP_MRP4R WHERE TEXT_2 IS NULL ;

 

--------------------------------------------------------------------------------

-- SET VARIABLES FOR PROCESSING

--------------------------------------------------------------------------------

OPEN CURSOR_01 ;

 

/*****************************************************************************/

/* Process Each new Record with the following action: */

/* 1 - Parse each column, looking for "~" as a string separator */

/* 2 - Assemble a tag and tag text in a new variable */

/* 3 - For each variable assembled, write a new row in FPARSED165 */

/* Process Each new Record with the following action: */

/*****************************************************************************/

--------------------------------------------------------------------------------

-- MAIN DATA INTAKE LOOP

--------------------------------------------------------------------------------

 

SET END_OF_FILE = 0 ;

 

SET SQLCODE = 0 ;

SET SQLSTATE = '00000' ;

 

---------------------------------------------------------------------

WHILE END_OF_FILE = 0 DO

 

 

FETCH CURSOR_01 INTO

W_MATERIAL_NUMBER ,

W_TEXT_1 ,

W_TEXT_2 ,

W_NOTES_RRN ;

 

IF SQLCODE <> 0

THEN

SET END_OF_FILE = 1 ;

END IF ;

 

---------------------------------------------------------------------

 

-- Do the first LOCATE to find out if there is any '~' Value in the string:

SET STRING_START = 1 ;

SET STRING_END = 0 ;

SET INNER_LOOP = 1 ;

SET STRING_END = LOCATE( '~' , W_TEXT_2 , 1) ;

 

-- In case there is ONLY ONE string with no "~" delimiter, the locate

-- keyword will yield a zero. Take the whole string instead.

 

IF STRING_START = 1 and STRING_END = 0

THEN SET STRING_END = 510 ;

END IF ;

 

-- Write first row, which will contain a general category descriptor.

 

---------------------------------------------------------------------

---------------------------------------------------------------------

-- Insert new row and look for next string marker.

---------------------------------------------------------------------

WHILE INNER_LOOP > 0

 

DO

 

----------------------------------------------------

 

SET STRING_LENGTH = STRING_END - STRING_START ;

IF STRING_LENGTH > 150

THEN -- LIMIT STRING LENGTH TO 150

SET STRING_LENGTH = 150 ;

END IF ;

 

INSERT INTO IMP_MRP4P

SELECT

W_MATERIAL_NUMBER ,

STRIP( SUBSTRING( W_TEXT_2 , STRING_START, STRING_LENGTH ) )

FROM SYSIBM/SYSDUMMY1 ;

 

----------------------------------------------------

 

SET STRING_START = STRING_START + STRING_LENGTH +1 ;

SET STRING_END = LOCATE( '~' , W_TEXT_2 , STRING_START ) ;

 

IF STRING_END <= 1

THEN SET INNER_LOOP = -1 ;

END IF ;

 

END WHILE ;

---------------------------------------------------------------------

--

---------------------------------------------------------------------

 

 

END WHILE ;

 

CLOSE CURSOR_01 ;

 

 

-- Before letting the file go, run a quick duplicate cleaner to ensure

-- no description is loaded twice by accident.

 

DELETE FROM IMP_MRP4S H1 WHERE RRN(H1) <

( SELECT MAX( RRN(H2) ) FROM IMP_MRP4S H2

WHERE H1.MATERIAL_NUMBER = H2.MATERIAL_NUMBER

AND H1.TEXT_1 = H2.TEXT_1 ) ;

 

 

END -- End of procedure