Monday, August 3, 2009

SQLLDR'DA DATE VERİTİPİ YÜKLEMESİ

--tab karakteri ile ayrılmış olan bir text dosya oluşturuyorum. Adını da isim_tarih.txt yapalım.
--aşağıdaki tabloda görüldüğü üzere farklı formatlarda yazılmış tarihler bulunuyor.
--Bazıları DD.MM.YYYY formatında bazıları DD:MM:YYYY HH24:MI:SS formatında.

levent cakir18.12.2007 22:51:25 200811
orhan eripek 28.03.2008 200811
ali ates 21.04.2008 10:20:57 200811
rafet cambaz 16.02.2008 16:38:00 200811
selcuk yilmaz 03.02.2006 200811
ali ates 28.04.2008 14:57:52 200811
ali ates 13.07.2002 200811

NOT : BURADA YAPIŞTIRIKEN TAB KARAKTERİ OLMADI SİZ KENDİNİZ ARALARINA TAB KARAKTENİ EKLEYİNİZ.

şimdi bu verileri yükleyeceğimiz tabloyu oluşturalım.

CREATE TABLE SQL_LOADER_DENEME
(
GSM VARCHAR2(20 BYTE),
START_DATE date,
YILAY VARCHAR2(10 BYTE)
)

daha sonra control file oluşturalım.

LOAD DATA
INFILE '/d104/isim_tarih.txt'
INTO TABLE sql_loader_deneme
FIELDS TERMINATED BY ' '
OPTIONALLY ENCLOSED BY '"'
(gsm,start_date DATE "dd:mm:yyyy hh24:mi:ss" ,yilay)

oluşturduğumuz bu control dosyamızı isim_tarih_control.ctl şeklinde kaydedelim.

şimdi sira sqlldr i çalıştırmaya geldi.

sqlldr userid=HR/******@ORCL control=/d104/isim_tarih_control.ctl log=/d104/isim_tarih_log.log

more /d104/isim_tarih_log.log dediğimizde aşağıdaki hataları görüyoruz.

TABLE create script'inde START_DATE sütünunu date formatında belirttiğimizde aşağıdaki hatayı alıyor.



Table SQL_LOADER_DENEME, loaded from every logical record.
Insert option in effect for this table: INSERT

Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
GSM FIRST * O(") CHARACTER
Terminator string : ' '
START_DATE NEXT * O(") DATE dd:mm:yyyy hh24:mi:ss
Terminator string : ' '
YILAY NEXT * O(") CHARACTER
Terminator string : ' '

Record 1: Rejected - Error on table SQL_LOADER_DENEME, column START_DATE.


şeklinde bir hatayı alıyoruz.

farklı formatta gelen tarihleri yükleme problemini aşmak için when kalıbıda kullanılabilinir. Fakat bizim alanlar tab ile ayrıldığı için öncelik ile bu yöntemi kullandım. Ama bu uzun yoldan olan bir çözüm .

öncelikle bir temp tablo oluşturuyoruz.

CREATE TABLE TMP_SQL_LOADER_DENEME
(
GSM VARCHAR2(20 BYTE),
START_DATE varchar2(30), -- yeni alanımız bu karakter tipinde
YILAY VARCHAR2(10 BYTE)
)

şimdi bu tabloya yüklemeyi yapıyoruz.

LOAD DATA
INFILE '/d104/isim_tarih.txt'
INTO TABLE TMP_SQL_LOADER_DENEME
FIELDS TERMINATED BY ' '
OPTIONALLY ENCLOSED BY '"'
(gsm,start_date,yilay)

sqlldr userid=HR/******@ORCL control=/d104/isim_tarih_control.ctl log=/d104/isim_tarih_log.log
yükleme işlemi başarılı bir şekilde gerçekleşiyor.

şimdi oluşturduğumuz bu temp tablodan verileri bizim kendi tablomuza aktarmaya sıra geldi.
iki farklı tarih formatımız olduğu için her birisi için ayrı ayrı insert scripti yazıyoruz.

INSERT INTO sql_loader_deneme
(SELECT gsm, TO_DATE (start_date, 'DD:MM:YYYY HH24:MI:SS') start_date,
yilay
FROM tmp_sql_loader_deneme
WHERE LENGTH (start_date) > 10)

INSERT INTO sql_loader_deneme
(SELECT gsm, TO_DATE (start_date, 'DD.MM.YYYY') start_date,
yilay
FROM tmp_sql_loader_deneme
WHERE LENGTH (start_date) <11)>

--oluştruduğumuz tabloyu silelim.

drop table tmp_sql_loader_deneme


SELECT COUNT(1) FROM SQL_LOADER_DENEME
-- 7 tane kayıt eklenmiş.
--şimdi log fileden bakalim kaç kayıt eklendiğine

Total logical records skipped: 0
Total logical records read: 7
Total logical records rejected: 0
Total logical records discarded: 0

aynı problemi kısa yolsan çözmek için aşağıdaki yontemi izleyebiliriz.
bu yöntem ile Oracle tarafında Varchar2 alanını date alanına cevirmemize gerek kalmaz.

önce deneme için char tipinde bir yükleme yapalım.

LOAD DATA
INFILE '/d102/bbb.txt'
INTO TABLE SQL_LOADER_deneme
WHEN (22)= ' '
(GSM POSITION(01:10) CHAR ,
START_DATE POSITION(12:21) CHAR,
YILAY POSITION(23:28) CHAR )
INTO TABLE SQL_LOADER_deneme
when (22)<>' '
--burada tab karakteri var
(GSM POSITION(01:10) CHAR ,
START_DATE POSITION(12:30) CHAR,
YILAY POSITION(32:37) CHAR )

control file bu şekilde oluşturduktan sonra çalıştırıyoruz

sqlldr userid=HR/******@ORCL control=/d104/isim_tarih_control.ctl log=/d104/isim_tarih_log.log

Bu yükleme örneği ile yukarıdaki arasında bir fark yok aslında sadece position belirledik.

Control file'ımızı biraz daha geliştirerek tablomuza direck olarak date tipinde yükleme yapabiliriz.
Burada hangi positionlarda date tipinin olduğunu belirledikten sonra o date tiplerine uygun olan dönüşüm tiplerini belirlemek gerekiyor.


LOAD DATA
INFILE '/d104/bbb.txt'
INTO TABLE SQL_LOADER_deneme
WHEN (22)= ' '
(GSM POSITION(01:10) CHAR ,
START_DATE POSITION(12:21) DATE "dd.mm.yyyy",
YILAY POSITION(23:28) CHAR )
INTO TABLE SQL_LOADER_deneme
when (22) < >' '
(GSM POSITION(01:10) CHAR ,
START_DATE POSITION(12:30) DATE "dd.mm.yyyy hh24:mi:ss",
YILAY POSITION(32:37) CHAR )

1 comment:

Anonymous said...

güzel çalışma, alicim ;)