26 Mayıs 2009 Salı

PLSQL kullanarak merkez bankası doviz kurlarını internetten alabilir miyim? (PART III)

Aşağıdaki prosedürü bir job içerisine yerleştirerek kullanıyorum.
Bu procedure ile birlikte döviz alma işlemini tamamlamış bulunuyoruz.
Burada ben dolar,sterlin ve euro ve çapraz kurları tabloya insert ediyorum.
Kodu değiştirerek istediğiniz kurları ekleyebilirsiniz.
Aşağıdaki kodu toad a yapıştırıp FormatCode(Shift+Ctrl+F)
tuşlarına basarsanız daha anlaşılır olacaktır.

----------------------------------------------------------
---Purpose : This procedure creates currency rates into PAR_CURRENCY_RATES table
--- via http://www.tcmb.gov.tr/kurlar/today.xml
--- This procedure runs in a job.
---Date : 28.05.2009
---Responsible :BAkverdi
----------------------------------------------------------
PROCEDURE Set_Daily_Currencies IS
gelen_data_ UTL_HTTP.html_pieces;
alinan_sayfa_ NUMBER;
gelen_data_textclob_ CLOB;
--xml parse ile ilgili degiskenler
l_parser DBMS_XMLPARSER.parser;
l_doc DBMS_XMLDOM.domdocument;
l_nl DBMS_XMLDOM.domnodelist;
l_n DBMS_XMLDOM.domnode;
l_temp VARCHAR2 (1000);

TYPE tab_type IS TABLE OF par_currency_rates%ROWTYPE;

t_tab tab_type := tab_type ();
l_nodemap DBMS_XMLDOM.domnamednodemap;
l_attr_node DBMS_XMLDOM.domnode;
--xml parse ile ilgili degiskenler
valid_date_ DATE;
para_birimi_ VARCHAR2 (50);
para_birimi_alis_ VARCHAR2 (100);
para_birimi_satis_ VARCHAR2 (100);
para_birimi_ortalama_deger_ NUMBER;
ortalama_usd_deger_ NUMBER;
ortalama_euro_deger_ NUMBER;
ortalama_gbp_deger_ NUMBER;
BEGIN
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
gelen_data_ :=
UTL_HTTP.request_pieces ('http://www.tcmb.gov.tr/kurlar/today.xml',
100);

--dbms_output.put_line(gelen_data_.count || ' pieces were retrieved.');
--dbms_output.put_line('with total length ');
IF gelen_data_.COUNT < 1
THEN
DBMS_OUTPUT.put_line ('0');
ELSE
DBMS_OUTPUT.put_line ( (2000 * (gelen_data_.COUNT - 1))
+ LENGTH (gelen_data_ (gelen_data_.COUNT))
);
END IF;

--dbms_output.put_line(gelen_data_(1));
alinan_sayfa_ := 1;
gelen_data_textclob_ := NULL;

IF gelen_data_.COUNT > 0
THEN
LOOP
gelen_data_textclob_ :=
gelen_data_textclob_ || gelen_data_ (alinan_sayfa_);
alinan_sayfa_ := alinan_sayfa_ + 1;

--dbms_output.put_line('sayfa : '||alinan_sayfa_);
IF alinan_sayfa_ = gelen_data_.COUNT + 1
THEN
EXIT;
END IF;
END LOOP;
END IF;

--dbms_output.put_line(gelen_data_textClob_);
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor


--Merkez bankasi XML inden doviz kurlarinin gecerlilik tarihi aliniyor..(valid_date_)
--Merkez bankasi XML inden doviz kurlarinin gecerlilik tarihi aliniyor..
-- Create a parser.
l_parser := DBMS_XMLPARSER.newparser;
-- Parse the document and create a new DOM document.
DBMS_XMLPARSER.parseclob (l_parser, gelen_data_textclob_);
l_doc := DBMS_XMLPARSER.getdocument (l_parser);
-- Free resources associated with the CLOB and Parser now they are no longer needed.
DBMS_LOB.freetemporary (gelen_data_textclob_);
DBMS_XMLPARSER.freeparser (l_parser);
-- Get a list of all the Tarih_Date nodes in the document using the XPATH syntax.
l_nl :=
DBMS_XSLPROCESSOR.selectnodes (DBMS_XMLDOM.makenode (l_doc),
'/Tarih_Date'
);
DBMS_OUTPUT.put_line (DBMS_XMLDOM.getlength (l_nl));
l_n := DBMS_XMLDOM.item (l_nl, 0);
--dbms_xslprocessor.valueOf(l_n,'Tarih/text()',gecici,null);
l_nodemap := DBMS_XMLDOM.getattributes (l_n);
l_attr_node := DBMS_XMLDOM.getnameditem (l_nodemap, 'Tarih');
valid_date_ :=
TO_DATE (DBMS_XMLDOM.getnodevalue (l_attr_node), 'DD.MM.YYYY');
DBMS_OUTPUT.put_line (valid_date_);
--Merkez bankasi XML inden doviz kurlarinin gecerlilik tarihi aliniyor..
--Merkez bankasi XML inden doviz kurlarinin gecerlilik tarihi aliniyor..


--Merkez bankasindan sadece usd,eur ve sterlin degerlerini aliyorum...
--Merkez bankasindan sadece usd,eur ve sterlin degerlerini aliyorum...
-- Get a list of all the Tarih_Date nodes in the document using the XPATH syntax.
l_nl :=
DBMS_XSLPROCESSOR.selectnodes (DBMS_XMLDOM.makenode (l_doc),
'/Tarih_Date/Currency'
);
DBMS_OUTPUT.put_line (DBMS_XMLDOM.getlength (l_nl));

-- Loop through the list and create a new record in a tble collection
-- for each EMP record.
FOR cur_dvz IN 0 .. DBMS_XMLDOM.getlength (l_nl) - 1
LOOP
l_n := DBMS_XMLDOM.item (l_nl, cur_dvz);
DBMS_XSLPROCESSOR.valueof (l_n, 'CurrencyName/text()', para_birimi_);

--dbms_output.put_line('para_birimi : '||para_birimi_); --tum para birimleri yaziyor
IF para_birimi_ IN ('US DOLLAR', 'EURO', 'POUND STERLING')
THEN
-- Use XPATH syntax to assign values to he elements of the collection.
-- 1 (TL) 2 (GBP) 3 (EURO) 4 (USD)
IF para_birimi_ = 'US DOLLAR'
THEN
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '4';
t_tab (t_tab.LAST).currency_to := '1';
END IF;

IF para_birimi_ = 'EURO'
THEN
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '3';
t_tab (t_tab.LAST).currency_to := '1';
END IF;

IF para_birimi_ = 'POUND STERLING'
THEN
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '2';
t_tab (t_tab.LAST).currency_to := '1';
END IF;

DBMS_XSLPROCESSOR.valueof (l_n,
'ForexBuying/text()',
para_birimi_alis_
);
DBMS_XSLPROCESSOR.valueof (l_n,
'ForexSelling/text()',
para_birimi_satis_
);
para_birimi_ortalama_deger_ :=
( TO_NUMBER (para_birimi_alis_, '999999999.9999')
+ TO_NUMBER (para_birimi_satis_, '999999999.9999')
)
/ 2;
t_tab (t_tab.LAST).VALUE := para_birimi_ortalama_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;

--BU DEGISKENLER CAPRAZ KURLAR ICIN KULLANILACAK
--HER DEGER TL KARSILIGINI IFADE EDIYOR
IF para_birimi_ = 'US DOLLAR'
THEN
ortalama_usd_deger_ := para_birimi_ortalama_deger_;
END IF;

IF para_birimi_ = 'EURO'
THEN
ortalama_euro_deger_ := para_birimi_ortalama_deger_;
END IF;

IF para_birimi_ = 'POUND STERLING'
THEN
ortalama_gbp_deger_ := para_birimi_ortalama_deger_;
END IF;
--BU DEGISKENLER CAPRAZ KURLAR ICIN KULLANILACAK
--HER DEGER TL KARSILIGINI IFADE EDIYOR
END IF;
END LOOP;

--Merkez bankasindan sadece usd,eur ve sterlin degerlerini aliyorum...
--Merkez bankasindan sadece usd,eur ve sterlin degerlerini aliyorum...


--Capraz kurlar gecici t_tab dizi tablosuna ekleniyor
--Capraz kurlar gecici t_tab dizi tablosuna ekleniyor
-- 1 (TL) 2 (GBP) 3 (EURO) 4 (USD)
--TL to GBP
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '1';
t_tab (t_tab.LAST).currency_to := '2';
t_tab (t_tab.LAST).VALUE := 1 / ortalama_gbp_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--TL to GBP
--TL to EUR
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '1';
t_tab (t_tab.LAST).currency_to := '3';
t_tab (t_tab.LAST).VALUE := 1 / ortalama_euro_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--TL to EUR
--TL to USD
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '1';
t_tab (t_tab.LAST).currency_to := '4';
t_tab (t_tab.LAST).VALUE := 1 / ortalama_usd_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--TL to USD
-- 1 (TL) 2 (GBP) 3 (EURO) 4 (USD)
--GBP to EURO
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '2';
t_tab (t_tab.LAST).currency_to := '3';
t_tab (t_tab.LAST).VALUE := ortalama_gbp_deger_ / ortalama_euro_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--GBP to EURO
--GBP to USD
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '2';
t_tab (t_tab.LAST).currency_to := '4';
t_tab (t_tab.LAST).VALUE := ortalama_gbp_deger_ / ortalama_usd_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--GBP to USD
-- 1 (TL) 2 (GBP) 3 (EURO) 4 (USD)
--EURO to GBP
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '3';
t_tab (t_tab.LAST).currency_to := '2';
t_tab (t_tab.LAST).VALUE := ortalama_euro_deger_ / ortalama_gbp_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--EURO to GBP
--EURO to USD
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '3';
t_tab (t_tab.LAST).currency_to := '4';
t_tab (t_tab.LAST).VALUE := ortalama_euro_deger_ / ortalama_usd_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--EURO to USD
-- 1 (TL) 2 (GBP) 3 (EURO) 4 (USD)
--USD to GBP
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '4';
t_tab (t_tab.LAST).currency_to := '2';
t_tab (t_tab.LAST).VALUE := ortalama_usd_deger_ / ortalama_gbp_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;
--USD to GBP
--USD to EURO
t_tab.EXTEND;
t_tab (t_tab.LAST).currency_from := '4';
t_tab (t_tab.LAST).currency_to := '3';
t_tab (t_tab.LAST).VALUE := ortalama_usd_deger_ / ortalama_euro_deger_;
t_tab (t_tab.LAST).valid_date := valid_date_;

--USD to EURO
--Capraz kurlar gecici t_tab dizi tablosuna ekleniyor
--Capraz kurlar gecici t_tab dizi tablosuna ekleniyor


--Hazirlanan DATA , PAR_CURRENCY_RATES tablosuna insert ediliyor
--Hazirlanan DATA , PAR_CURRENCY_RATES tablosuna insert ediliyor
--Eger valid date i ayni gun olan kayit varsa temizleniyor...
DELETE FROM par_currency_rates
WHERE valid_date = valid_date_;
--Eger valid date i ayni gun olan kayit varsa temizleniyor...
--Guncel data insert inden Insert ten once eski valid kayitlar invalid ediliyor.
UPDATE par_currency_rates set is_valid = 0 where is_valid = 1;

FOR cur_row IN t_tab.FIRST .. t_tab.LAST
LOOP
INSERT INTO par_currency_rates
(currency_from,
currency_to, VALUE,
valid_date,
is_valid
)
VALUES (t_tab (cur_row).currency_from,
t_tab (cur_row).currency_to, t_tab (cur_row).VALUE,
t_tab (cur_row).valid_date,
1
);
END LOOP;
--Hazirlanan DATA , PAR_CURRENCY_RATES tablosuna insert ediliyor
--Hazirlanan DATA , PAR_CURRENCY_RATES tablosuna insert ediliyor
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
--err_num := SQLCODE;
--err_msg := SUBSTR(SQLERRM, 1, 100);
DBMS_OUTPUT.put_line ( 'Error Number: '
|| SQLCODE
|| 'Error Message:'
|| SUBSTR (SQLERRM, 1, 100)
);
DBMS_LOB.freetemporary (gelen_data_textclob_);
DBMS_XMLPARSER.freeparser (l_parser);
DBMS_XMLDOM.freedocument (l_doc);
ROLLBACK;
END Set_Daily_Currencies;

23 Mayıs 2009 Cumartesi

PLSQL kullanarak merkez bankası doviz kurlarını internetten alabilir miyim? (PART II)

İçerisinde döviz kurlarını tutacağım tablo scripti aşağıdaki gibi.

CREATE TABLE DEVELOPER.PAR_CURRENCY_RATES
(
PAR_CURRENCY_RATES_ID NUMBER(10),
CURRENCY_FROM NUMBER(2),
CURRENCY_TO NUMBER(2),
VALUE NUMBER(10,3),
CREATE_DATE DATE,
VALID_DATE DATE,
IS_VALID NUMBER(1) DEFAULT 0
)

Burada;

PAR_CURRENCY_RATES_ID : primary key
CURRENCY_FROM : hangi currency
CURRENCY_TO : hangi currency ye dönüşecek
VALUE : dönüşüm çarpanı ne
CREATE_DATE : oluşturma trh.
VALID_DATE : Geçerlilik tarihi
IS_VALID : 1 ise en son geçerli olan kayıt. 0 ise valid değil

Bu tabloya hergün çalışan bir job içinden yazacağımız procedure miz
yoluyla kayıt ekleyeceğiz.

Sonraki yazıda bu procedure yi inceleyeceğiz.

18 Mayıs 2009 Pazartesi

PLSQL kullanarak merkez bankası doviz kurlarını internetten alabilir miyim?

Bu makalede belirli bir URL üzerinden
plsql kullanarakdosya transferini
anlatıyorum. Sonraki yazımda merkez bankası döviz
kurlarını bir tabloya insert etme örneğini
gerçekleştireceğiz.

PLSQL ile web uzerinden bir url iceriğinin alınması
için UTL_HTTP paketi kullanılabilir.
Aşağıdaki örnekte merkez bankası günlük döviz
kurları internet üzerinden alınmaktadır.
Bu şekilde herhangibir html,xml vb. tür dosya
alınabilir.

DECLARE
gelen_data_ utl_http.html_pieces;
alinan_sayfa_ NUMBER;
gelen_data_textClob_ CLOB;
--xml parse ile ilgili degiskenler
l_parser dbms_xmlparser.Parser;
l_doc dbms_xmldom.DOMDocument;
l_nl dbms_xmldom.DOMNodeList;
l_n dbms_xmldom.DOMNode;
l_temp VARCHAR2(1000);
TYPE tab_type IS TABLE OF PAR_CURRENCY_RATES%ROWTYPE;
t_tab tab_type := tab_type();
l_nodemap DBMS_XMLDOM.domnamednodemap;
l_attr_node DBMS_XMLDOM.domnode;
--xml parse ile ilgili degiskenler
BEGIN
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
gelen_data_ := utl_http.request_pieces('http://www.tcmb.gov.tr/kurlar/today.xml', 100);
dbms_output.put_line(gelen_data_.count || ' pieces were retrieved.');
dbms_output.put_line('with total length ');
IF gelen_data_.count < 1
THEN dbms_output.put_line('0');
ELSE dbms_output.put_line
((2000 * (gelen_data_.count - 1)) + length(gelen_data_(gelen_data_.count)));
END IF;
--dbms_output.put_line(gelen_data_(1));
alinan_sayfa_ := 1;
gelen_data_textClob_ := NULL;
IF gelen_data_.count > 0 THEN
LOOP
gelen_data_textClob_ := gelen_data_textClob_ || gelen_data_(alinan_sayfa_);
alinan_sayfa_ := alinan_sayfa_ + 1;
--dbms_output.put_line('sayfa : '||alinan_sayfa_);
IF alinan_sayfa_ = gelen_data_.count + 1 THEN
EXIT;
END IF;
END LOOP;
END IF;
dbms_output.put_line(gelen_data_textClob_);
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
--http://www.tcmb.gov.tr/kurlar/today.xml den gunluk doviz kurlari aliniyor
END;

Oracle 11g kullanıyorsanız yukarıdaki blok hata verecektir.
ORA-24247: network access denied by access control list (ACL)

Oracle 11g ile gelen ek güvenlik dolayısıyla eğer
11g kullanıyorsanız aşağıdaki kodları çalıştırarak
almak istediğiniz dosya ve url yi ACL içerisine
eklemelisiniz.Burada "DEVELOPER", yetki verilmek
istenilen oracle user dır.

begin
dbms_network_acl_admin.create_acl (
acl => 'today.xml',
description => 'merkez bankasi gunluk doviz kurlari',
principal => 'DEVELOPER',
is_grant => true,
privilege => 'connect',
start_date => null,
end_date => null
);
end;

begin
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(acl => 'today.xml',
principal => 'DEVELOPER',
is_grant => true,
privilege => 'resolve');
end;

begin
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(acl => 'today.xml',
host => 'www.tcmb.gov.tr');
end;

Bu güvenlik sistemi ile ilgili ayrıntılı bilgi için aşağıdaki
linki inceleyebilirsiniz.

http://johanlouwers.blogspot.com/2009/01/ora-24247-network-access-denied-by.html

Eğer başarıyla yetki verdiyseniz aşağıdaki SQL
çalıştığında sonuçlar arasında today.xml yer alacaktır.

select * from dba_network_acl_privileges