Skip to Main Content
  • Questions
  • WHEN clause in SQL Loader control file

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Pratima.

Asked: December 06, 2016 - 8:46 am UTC

Last updated: December 12, 2016 - 1:12 pm UTC

Version: 11.2.0.1.0

Viewed 10K+ times! This question is

You Asked

Hi Team,

We have a bank statement datafile provided in SWIFT940 standard format that has Cyrillic characters . On the basis of first 3 characters of lines we decide what information is provided in the line hence using POSITION is the only solution here.

Datafile example:

:20:9400124576021331
:25:200340027
:28:141
:60F:C160801KZT21637948,20
:61:1608010801CT70250000,00NFEX1162140060//1162140055
:86:059?00Commissions And Charges?20/PY/КПН ЗА НЕРЕЗИДЕНТА КОМПАН
И АО МХК ЕВРОХИМ РОССИЯ (ДОГОВОР ?21ЗАЙМА №001-0655165 ОТ 30.0
4.2015Г.).?22/BN/НАЛОГОВОЕ УПРАВЛЕНИЕ ПО БОСТАНДЫКСК?23/BI/KZ2407
0105KSN0000000?24/AB/KKMFKZ2A ГУ КОМИТЕТ КАЗНАЧЕЙСТВА МФ РК АЛМАТ
Ы KZ24070105KSN00?2500000?26/OA/KZT,
:62F:C160801KZT42536082,21
:64:C160801KZT42536082,21

In above datafile, record_id_no :86: has multiple lines.

If new line starts with multi-byte character, sql loder fails to load data. I tried using LIKE and NOT LIKE but it seems we can only use '=' and '<>' with WHEN. Is there any way to load such files?

Test CTL file :

LOAD DATA
CHARACTERSET UTF8
REPLACE
PRESERVE BLANKS

-- Record Type 61: Supplimentary Detail (set rec_id_no to 9)
INTO TABLE ce_stmt_int_tmp
WHEN rec_id_no not like ':%'
TRAILING NULLCOLS
(rec_no RECNUM,
rec_id_no POSITION(1:10) CHAR "decode(substr(rec_id_no,1,1), ':', '0', '9')",
column1 POSITION(1:80) CHAR)

-- Record Type 86: Information to Account Owner
INTO TABLE ce_stmt_int_tmp
WHEN rec_id_no like ':86%'
TRAILING NULLCOLS
(rec_no RECNUM,
rec_id_no POSITION(1:10) CHAR
TERMINATED BY WHITESPACE "ltrim(substr(rec_id_no,1,3), ':')",
column1 POSITION(5:2000) CHAR)


Kindly help in this regard.

Thanks,
Pratima

and Chris said...

To change your likes equalities, just compare the first N characters to your string. e.g.:

WHEN (1:3) = ':86'


To load records that span multiple lines you can use the str clause of infile. But you need a character to mark the end of records to do this!

For example, if you can have a pipe (|) at the end of each record, you can load multiple lines as one row with:

INFILE data.dat "STR '|\r\n'"


But you'll need your file to look something like this:

:20:9400124576021331|
:25:200340027|
:28:141|
:60F:C160801KZT21637948,20|
:61:1608010801CT70250000,00NFEX1162140060//1162140055|
:86:059?00Commissions And Charges?20/PY/КПН ЗА НЕРЕЗИДЕНТА КОМПАН
И АО МХК ЕВРОХИМ РОССИЯ (ДОГОВОР ?21ЗАЙМА №001-0655165 ОТ 30.0
4.2015Г.).?22/BN/НАЛОГОВОЕ УПРАВЛЕНИЕ ПО БОСТАНДЫКСК?23/BI/KZ2407
0105KSN0000000?24/AB/KKMFKZ2A ГУ КОМИТЕТ КАЗНАЧЕЙСТВА МФ РК АЛМАТ
Ы KZ24070105KSN00?2500000?26/OA/KZT|
:62F:C160801KZT42536082,21|
:64:C160801KZT42536082,21|

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Not useful with multi-byte characters

Pratima Shukla, December 09, 2016 - 5:39 am UTC

First of all thanks a lot for your update.

We cannot modify datafile as it's provided by the bank and follows universal standard format. I tried the solution you suggested and made below changes in control file.

INTO TABLE ce_stmt_int_tmp
WHEN (1:2) <> ':8' AND (1:2) <> ':2' AND (1:2) <> ':6'
TRAILING NULLCOLS
(rec_no RECNUM,
rec_id_no POSITION(1:2) CHAR "decode(substr(:rec_id_no,1,1), ':', '0', '9')",
column1 POSITION(1:200) CHAR)

but it fails if 2nd character is Cyrillic.

Example:
/АО КТЖ - ГРУЗОВЫЕ ПЕРЕВОЗКИ?24/BI/KZ716010111000282782?25/AB/HS
АТФБАНК АЛМАТЫ KZ97826A1KZTD2005700?26/OA/KZT,
УСЛУГ ПО ЖЕЛЕЗНОДОРОЖНЫМ ПЕРЕВОЗКАМ?21 АО КТЖ - ГРУЗОВЫЕ ПЕРЕВОЗ
МЕБЕЛИ, СОГЛАСНО СЧЕТА НА ОПЛАТУ №1?2114ОТ 27.07.16Г., В Т.Ч. НД
АО НЕФТЯНАЯ СТРАХОВАЯ К?23/BI/KZ418560000000050956?24/AB/KCJBKZ
№000000008 ОТ 29.07.2016Г. БЕЗ НДС.?22/BN/ИП ВАСИЛЕНКО?23/BI/KZ
/ТОО ALACARD PETROLTECH?24/BI/KZ97826A1KZTD2005700?25/AB/ALMNKZKA
АО АТФБАНК АЛМАТЫ KZ97826A1KZTD2005700?26/OA/KZT,
И Ж/Д БИЛЕТОВ , СОГЛАСНО СЧЕТА НА ОПЛА?21ТУ№59 ОТ 28.07.2016Г. Б
НДС 1 092 505-50 ТЕНГЕ.?22/BN/ТОО LOGIC SYSTEM LTD?23/BI/KZ3796

Is there any way to consider characters instead of bytes in 'WHEN' clause as any position in a line can have multi-byte character in a datafile?


Chris Saxon
December 09, 2016 - 4:31 pm UTC

You can specify character or byte length semantics as part of the characterset parameter:

http://docs.oracle.com/database/122/SUTIL/oracle-sql-loader-control-file-contents.htm#SUTIL1088

'characterset UTF8 length semantics char' helped

Pratima Shukla, December 12, 2016 - 11:52 am UTC

Hi Chris,

Suggested note helped and issue got resolved.

Thanks a lot for all the time and effort you put to help me out.

Best Regards,
Pratima
Chris Saxon
December 12, 2016 - 1:12 pm UTC

Good to hear!