AZEROUG qrupunun 14 Sentyabr görüşü baş tutdu.

Posted on 16 Sentyabr 2013. Filed under: Java, JDBC, Oracle, PL/SQL, SQL | Etiketlər: , , , , , |

14 Sentyabr 2013 tarixində AZEROUG qrupunun növbəti görüşü Azercell Plazada baş tutdu. Təxmini 60 nəfər iştirakçı var idi.

Təşkilati dəstəyə görə Azercell Barama İnnovasiya mərkəzinə təşəkkürümü bildirirəm.

Bu görüşdə Oracle PL/SQL proqramlaşdırma ilə bağlı 2 təqdimat oldu.

Mənim təqdimatım Oracle 12c verilənlər bazasında proqramçılar üçün təqdim edilmiş yeniliklər haqda idi. Təqdimatda SQL, PL/SQL və JDBC ilə bağlı yeniliklər haqda məlumat verdim, VirtualBoxda qurulmuş Oracle 12c bazasında nümunə scriptlər göstərdim.

Təqdimatı buradan yükləyə bilərsiniz.

Görüşdən bəzi şəkillərə baxa bilərsiniz.

Advertisements
Tam Yazını Oxu | Make a Comment ( None so far )

“ORA-01722: invalid number” ilə “ORA-06502: numeric or value error” xətalarının fərqi

Posted on 1 May 2011. Filed under: Oracle, PL/SQL, SQL | Etiketlər: , , , , |

Aşağıdakı kodlara baxıb baş verəcək Oracle xətasını müəyyənləşdirməyə çalışın.

-- Nümunə kod 1
select to_number('123a') from dual
-- Nümunə kod 2
declare
    l_number number;
begin
    select to_number('123a') into l_number from dual;
    dbms_output.put_line(l_number);
end;
-- Nümunə kod 3
declare
    l_number number;
begin
    l_number := to_number('123a');
    dbms_output.put_line(l_number);
end;

Nümunə kod 1-də ORA-01722: invalid number xətası çıxacaq.
Nümunə kod 2-də ORA-01722: invalid number xətası çıxacaq.
Nümunə kod 3-də ORA-06502: PL/SQL: numeric or value error: character to number conversion error xətası çıxacaq.

Yuxarıdakı nümunə kodlardan göründüyü kimi “ORA-01722: invalid number” xətası SQL sorğusunda baş verir, bu SQL sorğusu PL/SQL proqramında da ola bilər(nümunə 2-də olduğu kimi).

“ORA-06502: numeric or value error” xətası isə ancaq PL/SQL proqramında baş verir.
Məntiqi olaraq bunların hər ikisi eyni xəta olsa da xətanın baş vermə yerinə görə(SQL və ya PL/SQL context) Oracle onlara ayrı xəta kodları və mesajı vermişdir. Buna görə də diqqətli olub PL/SQL proqramının exception handler kodlarında bu nüansı nəzərə almaq lazımdır.

Yuxarıdakı nümunə 2 və 3-də verilmiş PL/SQL kodlarını düzgün exception handler ilə aşağıdakı kimi olmalıdır:

-- Nümunə kod 2
declare
    l_number number;
begin
    select to_number('123a') into l_number from dual;
    dbms_output.put_line(l_number);
exception
    when INVALID_NUMBER then
        dbms_output.put_line('SQL invalid number error ' || dbms_utility.format_error_backtrace);
        dbms_output.put_line('SQL invalid number error ' || dbms_utility.format_error_stack);
end;
-- Nümunə kod 3
declare
    l_number number;
begin
    l_number := to_number('123a');
    dbms_output.put_line(l_number);
exception
    when VALUE_ERROR then
        dbms_output.put_line('PL/SQL value error ' || dbms_utility.format_error_backtrace);
        dbms_output.put_line('PL/SQL value error ' || dbms_utility.format_error_stack);
end;

Ümid edirəm ki, aydın oldu. Happy PL/SQL development 🙂

Tam Yazını Oxu | Make a Comment ( 2 so far )

7 May Oracle konfransı

Posted on 11 Aprel 2011. Filed under: Oracle, Seminar | Etiketlər: , , , , |

7 May tarixində CETÜRK tərəfindən təşkil olunan Oracle konfransında “Oracle proqramçı karyerası” ilə bağlı çıxış edəcəyəm.
Təqdimatda aşağıdakı mövzulara toxunacağam:
1.Oracle proqramçı nələri bilməlidir?
2.Oracle proqramçı necə olmaq olar?
3.Oracle proqramçılar üçün iş imkanları
4.Oracle SQL və PL/SQL sertifikatları haqqında

Tarix: 7 May şənbə günü saat 10:00-18:00
Yer: Azərbaycan Texniki Universiteti
Yer: Gəncliyə Yardım Fondu, Bakı şəhəri, Səbail rayonu, Cəfərov Qardaşları küçəsi 16

Ətraflı məlumat: http://www.ceturk.com/ceturk-azerbaycan-oracle-konferansi
Oracle ilə maraqlanan hər kəs dəvətlidir.

Tam Yazını Oxu | Make a Comment ( 11 so far )

Java proqramından PL/SQL cursorunun istifadəsi

Posted on 19 Fevral 2011. Filed under: Java, JDBC, Oracle, PL/SQL | Etiketlər: , , , , , |

Bu yazıda Java proqramında PL/SQL prosedurunda təyin olunmuş cursor-un istifadəsini izah edəcəm.
Bunun üçün PL/SQL proqramlarında cursor-un nə olduğunu və necə istifadə olunduğunu bildiyinizi fərz edirəm.

Nümunə HR sxeması üzərində belə bir məsələyə baxaq.
Elə bir PL/SQL proqramı yazmaq lazımdır ki, ona verilmiş işçi əgər hansısa bir şöbənin rəhbəridirsə, onda həmin şöbədəki bütün prosedur işçilərin siyahısını qaytarsın. Əgər verilmiş işçi heç bir şöbənin rəhbəri deyilsə, onda özü və əgər varsa, onun tabeliyində olan işçilərin siyahısını qaytarmaq lazımdır. Prosedurdan qayıdan nəticə ona giriş olaraq göndərilmiş işçinin vəziyyətindən asılıdır.
Bu məsələnin cavabı olaraq aşağıdakı PL/SQL proqramını yazmaq olar.

create or replace procedure test_dyn_manager(p_employee_id in number, p_employee_list out sys_refcursor)
is
  l_dept_id number;
  cursor dept_cur 
  is 
    select department_id from departments
    where manager_id=p_employee_id;
begin
  open dept_cur;
  fetch dept_cur into l_dept_id;
  close dept_cur;
  
  if l_dept_id is not null
  then 
    open p_employee_list for 'select employee_id, first_name, last_name, job_id ' ||
      ' from employees where department_id='||l_dept_id || 
      ' order by department_id';      
  else
    open p_employee_list for 
      'select employee_id, first_name, last_name, job_id from employees where manager_id='||p_employee_id ||
      ' union all ' ||
      ' select employee_id, first_name, last_name, job_id from employees where employee_id='||p_employee_id ||
      ' order by employee_id'; 
  end if;
end test_dyn_manager;

Bu prosedurda əvvəlcə işçinin hər hansı bir şöbənin rəhbəri olub olmadığı yoxlanılır.
Əgər şöbə rəhbəridirsə, onda out parametr olaraq təyin olunmuş p_employee_list cursoru həmin şöbədəki işçilərin siyahını verən select sorğusu ilə əlaqələndirilir. Əgər işçi şöbə rəhbəri deyilsə, onda p_employee_list cursoru işçinin özünü və varsa, onun tabeliyindəki işçiləri verən select sorğusu ilə əlaqələndirilir.

Bu proseduru yoxlamaq üçün aşağıda anonim PL/SQL blokunu yazaq.

declare
  --l_emp_id number:= 103; -- Alexander	Hunold IT sobesinin rehberi
  --l_emp_id number := 101; -- Neena	Kochhar sobe rehberi deyil, amma tabeliyinde isciler var   
  l_emp_id number:= 204; -- Hermann Baer rehber deyil, sade iscidir
  l_emp_list sys_refcursor;  
  l_id number;
  l_first_name employees.first_name%type;
  l_last_name employees.last_name%type;
  l_job_id employees.job_id%type;
Begin
  test_dyn_manager(l_emp_id, l_emp_list);
  loop
    fetch l_emp_list into l_id, l_first_name, l_last_name, l_job_id;    
    exit when l_emp_list%notfound;
    dbms_output.put_line('Emp_id=' || l_id || ' first_name=' || l_first_name || ' last_name=' || l_last_name || ' job_id=' || l_job_id);
  end loop;
  close l_emp_list;
end;

İndi isə yazdığımız proseduru Java proqramından çağırıb istifadə edək. Aşağıdakı proseduru çağırmaq üçün lazım olan minimum kod blokunu verirəm. Proqramın tam kodunu yazının sonundakı linkdən proyekti yükləyərək əldə edə bilərsiniz.

            long id = 103;
            String firstName = "";
            String lastName = "";
            String job = "";
            
            String sql = "{call test_dyn_manager(?,?)}";
            callableStatement = connection.prepareCall(sql);
            callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
            callableStatement.setLong(1, id);
            callableStatement.executeUpdate();
            ResultSet rs = (ResultSet) callableStatement.getObject(2);

            while(rs.next()) {
                id = rs.getLong("employee_id");
                firstName = rs.getString("first_name");
                lastName = rs.getString("last_name");
                job = rs.getString("job_id");            
                System.out.print("Id = " + id);
                System.out.print(" employee = " + firstName + " " + lastName);
                System.out.print(" job " + job);
                System.out.println();
            }

Prosedurun 2-ci parametrini out olaraq təyin etmək lazımdır. Bu zaman tip olaraq OracleTypes.CURSOR göstərilməlidir ki, sys_refcursor tipli bu parametrin Javada ResultSet obyekti olaraq oxumaq mümkün olsun.

Ümid edirəm ki, aydın oldu.
Proqramın tam versiyasını aşağıdakı linkdən yükləyə bilərsiniz.
http://www.boxca.com/70cfriqt1gsh/JdbcSysRefCursor.zip.html
Oracle bazasına qoşulmaq üçün lazımi konfiqurasiya məlumatları database.properties faylında yazılıb, öz sisteminizə uyğun dəyişə bilərsiniz.
Prosedurun kodu və test sql, pl/sql sorğuları database.sql faylına yazılıb.

Sual, tənqid və təkliflərinizi şərh olaraq yaza bilərsiniz.
Uğurlar!

Tam Yazını Oxu | Make a Comment ( 4 so far )

Java ilə Oracle PL/SQL proqramlarının istifadəsi

Posted on 15 Fevral 2011. Filed under: Java, JDBC, Oracle, PL/SQL | Etiketlər: , , , , , , |

Bu yazıda Oracle verilənlər bazasındakı PL/SQL prosedur və funksiyalarının Java proqramında istifadəsini göstərəcəyəm.
Nümunə olaraq HR sxemasındakı EMPLOYEES cədvəlini istifadə edəcəyəm.
Əvvəlcə EMPLOYEES cədvəlinə yeni işçi əlavə etmək üçün aşağıdakı PL/SQL prosedurunu yazaq.

create or replace procedure add_employee(
  p_employee_id out employees.employee_id%type,
  p_first_name in employees.first_name%type,
  p_last_name in employees.last_name%type,
  p_email in employees.email%type,
  p_hire_date in employees.hire_date%type,
  p_salary in employees.salary%type,
  p_department_id in employees.department_id%type,
  p_job_id in employees.job_id%type
)
is
begin
  select employees_seq.nextval into p_employee_id from dual;

  -- Oracle 11g bazasında sequence obyektini aşağıdakı kimi istifadə etmək mümkündür. 
  --p_employee_id := employees_seq.nextval;
  
  insert into employees(employee_id, first_name, last_name, email, hire_date, salary, department_id, job_id)
  values( p_employee_id, p_first_name, p_last_name, p_email, p_hire_date, p_salary, p_department_id, p_job_id);
end add_employee;

Bu prosedurda yeni işçiyə aid id sütununun avtomatik generasiyası üçün EMPLOYEES_SEQ obyekti istifadə olunur və onun qiyməti p_employee_id parametrinə mənimsədilib geri qaytarılır. Buna görə də həmin parametr out olaraq təyin edilib.

Bu prosedurunu aşağıdakı anonim PL/SQL bloku ilə yoxlamaq olar.

DECLARE
  l_new_emp_id NUMBER;
BEGIN
  add_employee(p_employee_id => l_new_emp_id, p_first_name => 'Ulvi', p_last_name => 'Qasimov', 
      p_department_id => 60, p_job_id => 'IT_PROG', p_email => 'ulvi@yahoo.com', 
      p_hire_date => to_date('14.02.2011', 'dd.mm.yyyy'), p_salary => 2000);
  dbms_output.put_line('Yeni isci kodu =  ' || l_new_emp_id);
END;

Bu proseduru Java proqramından aşağıdakı kimi çağırmaq olar. Aşağıda ancaq lazımi kod bloklarını yazmışam, proyektin tam versiyasını aşağıdakı linkdən yükləyə bilərsiniz.
Java ilə PL/SQL prosedur və funksiyasını çağırmaq üçün CallableStatement sinifi istifadə olunmalıdır.

String sql = "";
CallableStatement callableStatement = null;
// Yeni isci elave etmek
long id = 0;
String firstName = "Əli";
String lastName = "Əliyev";
String email = "ali@yahoo7.com";
double salary = 2222.0;
String job = "IT_PROG";
Date hireDate = new Date(); // bu gunku tarix
long department = 60;

// ? işarələri parametrləri göstərir, sırasına uyğun olaraq məlumatları vermək lazımdır.
sql = "{call add_employee(?,?,?,?,?,?,?,?)}";
callableStatement =  connection.prepareCall(sql);

// 1-ci parameter <strong>p_employee_id</strong> out parametr olduğuna görə onu ayrıca qeyd etmək lazımdır. 
callableStatement.registerOutParameter(1, Types.INTEGER);
callableStatement.setString(2, firstName);
callableStatement.setString(3, lastName);
callableStatement.setString(4, email);
callableStatement.setDate(5, convert(new Date()));
callableStatement.setDouble(6, salary);
callableStatement.setLong(7, department);
callableStatement.setString(8, job);
// proseduru işlədirik
callableStatement.executeUpdate();
// p_employee_id parametrinin qiymətini çap edirik
id = callableStatement.getLong(1);
System.out.println("Yeni isci kodu = " + id);

Burada bir neçə vacib məqamlar var:
1.JDBC ilə PL/SQL prosedurunu çağırmağın sintaksisi aşağıdakı kimidir:
{call prosedur_adı(parametr1, parametr2, … parametrN)}
Burada hər bir parametr üçün bir sual işarəsi yazılmalıdır.
2.Out parametrlər aşağıdakı kimi təyin edilməlidir:
callableStatement.registerOutParameter(parametr_sira_nomresi, parametr_tipi);
Parametr tipi olaraq java.sql.Types sinifindəki sabit qiymətlərdən uyğun olanı göstərmək lazımdır.
3.executeUpdate() metodu ilə proseduru işlədirik və bundan sonra out parametrlərinin qiymətini oxuyuruq.

İndi isə PL/SQL funksiyasının Java ilə necə istifadə olunmağına baxaq.
Əvvəlcə aşağıdakı kimi sadə bir funksiya yazaq.

create or replace function topla(a in number, b in  number)
return number
is
begin 
  return a+b;
end topla;

Bu funksiyanı Java proqramından aşağıdakı kimi çağıra bilərik.

sql = "{call ? := topla(?,?)}";
callableStatement = connection.prepareCall(sql);
callableStatement.registerOutParameter(1, Types.INTEGER);
callableStatement.setInt(2, 5);
callableStatement.setInt(3, 7);
callableStatement.executeUpdate();
int netice = callableStatement.getInt(1);
System.out.println("Netice = " + netice);

Burada vacib olan məqam funksiyadan qayıdan qiymətin java ilə necə oxunmasıdır.
? := ifadəsində bərabərlikdən əvvəlki ? işarəsi funksiyadan qayıdan qiyməti saxlayan parametrdir və out rejimində təyin edilməlidir.

Ümid edirəm ki, aydın oldu.
Proyektin tam kodunu aşağıdakı linkdən yükləyə bilərsiniz.
http://www.boxca.com/qqsybk73v3ll/JdbcPlsql.zip.html

Tam Yazını Oxu | Make a Comment ( 1 so far )

Oracle PL/SQL proqramlarında asılılıqların idarəsi

Posted on 7 Sentyabr 2010. Filed under: PL/SQL | Etiketlər: , , , |

Bu yazıda Oracle 10g və 11g VBİS-lərində PL/SQL proqramlarında asılılıqları idarəsi və fərqlərini izah etməyə izah edəcəm.

Oracle VBİS-i PL/SQL proqramlarının digər obyektlərdən asılılığını tam obyekt səviyyəsində izləyir. Bu o deməkdir ki, hər hansı bir cədvələ yeni sütun əlavə edilsə, ondan asılı olan bütün obyektlər(view, procedure, function və s.) avtomatik olaraq invalid olacaq. Amma bizim prosedur məntiqi olaraq yeni əlavə edilmiş sütundan asılı deyil, onu istifadə etmir. Eyni məsələ bizim prosedurun select etmədiyi hər hansı bir sütunun tipinin dəyişməsi üçün də keçərlidir. Cədvəlin hər hansı bir sütunu dəyişdirildikdə, bizim prosedur ondan asılı olmasa da Oracle VBİS-i onu avtomatik olaraq invalid edir. Oracle 11g VBİS-də bu vəziyyət müsbət yöndə dəyişdirilmişdir. Artıq Oracle 11g VBİS-i asılılıqları tam obyekt səviyyəsində yox, daha kiçik səviyyədə izləyə bilir.

Bu məsələyə əvvəlcə Oracle 10g VBİS üzərində baxaq.

SYS istifadəçisi ilə Oracle 10g VBİS-nə qoşuluruq.

HR istifadəçisi altında aşağıdakı paketi yaradırıq:

create or replace package hr.pkg_test
is
    function get_manager(p_employee_id in number) return varchar2;    
end pkg_test;

create or replace package body hr.pkg_test
as
    function get_manager(p_employee_id in number) 
    return varchar2
    is
        l_manager varchar2(50);
    begin
        select m.first_name || ' ' || m.last_name into l_manager 
        from hr.employees e, hr.employees m 
        where e.manager_id=m.employee_id and e.employee_id=p_employee_id;
        
        return l_manager;
    end get_manager;    
end pkg_test;

Yeni yaratdığımız paketin cari vəziyyətini yoxlayırıq.

select object_name, object_type, status 
from all_objects
where owner='HR' and object_name='PKG_TEST'

Paket içərisindəki GET_MANAGER funksiyası verilmiş işçi koduna əsasən onu rəhbərinin adını, soyadını qaytarır. Bu funksiya HR.EMPLOYEES cədvəlinin EMPLOYEE_ID, MANAGER_ID, FIRST_NAME və LAST_NAME sütunlarından asılır. Bu cədvəlin strukturu aşağıdakı kimidir:

İndi isə bu cədvəldəki email sütununu aşağıdakı kimi dəyişək:

alter table hr.employees
modify email varchar2(40);

Paketin cari vəziyyətinə baxaq:

Gördüyünüz kimi GET_MANAGER funksiyası email sütunundan asılı olmasa, bütün paket invalid oldu.

GET_MANAGER funksiyasını istifadə etsək, Oracle əvvəlcə paketi kompilyasiya edəcək, statusu valid olduqdan sonra onu istifadə etməyimizə imkan verəcək.

select hr.pkg_test.get_manager(110)  from dual;


Oracle 11g VBİS-də asılılıqların idarəsi daha da inkişaf etdirilmilmişdir, artıq PL/SQL proqramlarının asılılığı obyektin içindəki elementlər səviyyəsində izlənilir. Eyni əməliyyatları Oracle 11g VBİS-də yoxlayaq.

Əvvəlcə SYS istifadəçisi ilə Oracle 11g VBİS-nə qoşuluruq.

Eyni paketi yeni bazada yaradıb vəziyyətini yoxlayaq:

Email sütununu aşağıdakı kimi dəyişib paketin statusunu təkrar yoxlayaq:

alter table hr.employees
modify email varchar2(40);


Gördüyünüz kimi paketin statusu valid olaraq qaldı, çünki o email sütunundan asılı deyil.

İndi isə manager_id sütununu aşağıdakı kimi dəyişək və paketin cari vəziyyətinə baxaq:

alter table hr.employees
modify manager_id number(7);


Gördüyünüz kimi manager_id sütunu dəyişildikdən sonra paket avtomatik olaraq invalid oldu, çünki həmin sütun get_manager funksiyasında istifadə olunur.

Fine-grained dependency haqqında daha ətraflı məlumat almaq üçün aşağıdakı qaynağa müraciət edə bilərsiniz:

Oracle® Database Advanced Application Developer’s Guide, 11g Release 2 (11.2), Part Number E10471-05, “18.Schema Object Dependency”


Ümid edirəm ki, Oracle 11g VBİS-dəki bu yenilik aydın oldu. Sual, tənqid və təklifləriniz üçün şərh yazmaqdan çəkinməyin!
Uğurlar!

Tam Yazını Oxu | Make a Comment ( 2 so far )

XSL ilə SQL əmrlərinin generasiyası

Posted on 11 Avqust 2010. Filed under: OES, SQL | Etiketlər: , , , , , , |

Oracle Errors&Solutions proyekti ilə əlaqədar bütün Oracle versiyaları üçün olan xəta kodlarını və onlar haqqında məlumatı Oracle bazasına yazmaq lazım idi. Oracle xətaları XML faylında aşağıdakı kimi mövcuddur. Oracle 11g R2 VBİS üçün 12033 ədəd xəta kodu var, aşağıdakı nümunədə sadəcə 5 xəta kodu göstərilmişdir

<?xml version="1.0" encoding="UTF-8"?>
<error-list>
	<error id="ORA-00000">
		<code>ORA-00000: normal, successful completion</code>
		<cause>Normal exit.</cause>
		<action>None</action>
	</error>
	<error id="ORA-00001">
		<code>ORA-00001: unique constraint (string.string) violated</code>
		<cause>An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode, you may see this message if a duplicate entry exists at a different level.</cause>
		<action>Either remove the unique restriction or do not insert the key.</action>
	</error>
	<error id="ORA-00017">
		<code>ORA-00017: session requested to set trace event</code>
		<cause>The current session was requested to set a trace event by another session.</cause>
		<action>This is used internally; no action is required.</action>
	</error>
	<error id="ORA-00018">
		<code>ORA-00018: maximum number of sessions exceeded</code>
		<cause>All session state objects are in use.</cause>
		<action>Increase the value of the SESSIONS initialization parameter.</action>
	</error>
	<error id="ORA-00019">
		<code>ORA-00019: maximum number of session licenses exceeded</code>
		<cause>All licenses are in use.</cause>
		<action>Increase the value of the LICENSE MAX SESSIONS initialization parameter.</action>
	</error>
</error-list>

Bu XML faylındakı məlumatları Oracle bazasına köçürmək lazım idi. Cədvəlin strukturu aşağıdakı kimidir.

CREATE TABLE OES_11GR2_ERRORS
(
  ID      NUMBER PRIMARY KEY,
  CODE    VARCHAR2(10 CHAR),
  ERROR   VARCHAR2(1000 CHAR),
  CAUSE   VARCHAR2(1500 CHAR),
  ACTION  VARCHAR2(1500 CHAR)
);

İD sütunu primary key olduğuna görə onun qiymətlərini avtomatik generasiya etmək üçün aşağıdakı sequence obyekti istifadə etdim.

CREATE SEQUENCE OES_SEQ
START WITH 1
MINVALUE 1;

İndi isə XML faylındakı məlumatların əsasında SQL insert əmrləri hazırlamaq üçün aşağıdakı kimi XSL faylını hazırladım.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="error-list">
    <xsl:for-each select="error">
        <xsl:variable name="code" select="normalize-space(code)"></xsl:variable>
	<xsl:variable name="cause" select="normalize-space(cause)"></xsl:variable>
	<xsl:variable name="action" select="normalize-space(action)"></xsl:variable>
insert into OES_11GR2_ERRORS(id, error, cause, action) values(oes_seq.nextval, q'{<xsl:value-of select="$code"/>}', q'{<xsl:value-of select="$cause"/>}', q'{<xsl:value-of select="$action"/>}');
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Mətn içərisində olan ‘,”,\,& və s. xüsusi simvolları bazaya düzgün şəkildə daxil etmək üçün onları q'{}’ içərisində yazdım. Bu sayədə xüsusi simvollar düzgün şəkildə escape olundu.

Transformer proqramı ilə XML faylına XSL faylındakı çevrilmə qaydalarını tətbiq edərək aşağıdakı kimi SQL insert kodları generasiya etdim.

insert into OES_11GR2_ERRORS(id, error, cause, action) values(oes_seq.nextval, q'{ORA-00000: normal, successful completion}', q'{Normal exit.}', q'{None}');

insert into OES_11GR2_ERRORS(id, error, cause, action) values(oes_seq.nextval, q'{ORA-00001: unique constraint ( string string ) violated}', q'{An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode, you may see this message if a duplicate entry exists at a different level.}', q'{Either remove the unique restriction or do not insert the key.}');

insert into OES_11GR2_ERRORS(id, error, cause, action) values(oes_seq.nextval, q'{ORA-00017: session requested to set trace event}', q'{The current session was requested to set a trace event by another session.}', q'{This is used internally; no action is required.}');

insert into OES_11GR2_ERRORS(id, error, cause, action) values(oes_seq.nextval, q'{ORA-00018: maximum number of sessions exceeded}', q'{All session state objects are in use.}', q'{Increase the value of the SESSIONS initialization parameter.}');

insert into OES_11GR2_ERRORS(id, error, cause, action) values(oes_seq.nextval, q'{ORA-00019: maximum number of session licenses exceeded}', q'{All licenses are in use.}', q'{Increase the value of the LICENSE MAX SESSIONS initialization parameter.}');

Transformer proqramı haqqında bu yazıda qeyd etmişəm.
Cədvəldəki CODE sütununun qiymətini ERROR sütünundan ilk 9 simvolu(ORA-XXXXX) götürməklə aşağıdakı kimi əldə etmək mümkündür.

update oes_11gr2_errors set code=substr(error, 1, 9);
commit;

Ümid edirəm ki, bu yazı kimin üçünsə faydalı olar 🙂

Tam Yazını Oxu | Make a Comment ( None so far )

Java JDBC texnologiyası ilə CLOB və BLOB tipli məlumatlarla işləmək

Posted on 18 İyul 2010. Filed under: Java, JDBC, Oracle, PL/SQL, SQL | Etiketlər: , , , , |

Verilənlər bazasında böyük həcmdə mətn və qeyri mətn(şəkil, musiqi, video və s.) formatında məlumat saxlamaq üçün CLOB və BLOB tipləri istifadə olunur. CLOB(Character Large Object) böyük həcmdə mətn tipli məlumatları, BLOB(Binary Large Object) isə mətn tipli olmayan istənilən məlumatı(video, musiqi, şəkil, MS Office faylları, zip faylları və s.) bazada saxlamaq üçün istifadə olunur.

Java JDBC texnologiyası bütün verilənlər bazalarında CLOB və BLOB tipli məlumatlarla işləmək üçün universal imkan verir. Bu yazıda həmin imkan ətraflı izah ediləcək və nümunə proyekt üzərində əyani şəkildə göstiləcək.

İstifadə olunmuş proqram təminatı aşağıdakı kimidir:

  1. Netbeans 6.9 – open source
  2. Oracle Database 10g R2 Express Edition – pulsuz
  3. Oracle SQL Developer 2.1 – pulsuz

Nümunə olaraq LobManager adlı proyektdə CLOB və BLOB tipli məlumatların bazadan oxunması və yazılması göstəriləcək. Proyekt bloq yazılarında göstərilən kod nümunələrini CLOB olaraq, proqramın ekran görüntüsünü isə BLOB olaraq verilənlər bazasında saxlayan proqramdan ibarət olacaq. Bu proyektdə istifadə olunacaq cədvəlin strukturu aşağıdakı kimidir:

create table program_code(
    id number primary key,
    name varchar2(50), -- name for program source code
    description varchar2(200), -
    source clob, - program source code
    image blob – printscreen
);

İD sütunun primary key olaraq təyin edilmişdir, onun qiymətlərini avtomatik olaraq daxil etmək üçün aşağıdakı kimi bir sequence obyekti yaradaq.

create sequence program_code_seq
minvalue 1
increment by 1;

Əvvəlcə bu cədvələ nümunə məlumat daxil edək. Aşağıdakı anonim PL/SQL kod blokunu Oracle SQL Developer-də işlədək.

declare
 l_new_id number;
begin
 select program_code_seq.nextval into l_new_id from dual;
 insert into program_code(id, name, description) values(l_new_id, 'LobManager', 'Read and write LOB/CLOB data using Java');
 commit;
end;

Oracle 11g VBİS-də sequence obyektini bir başa istifadə etmək mümkündür, amma bu proyektdə Oracle 10g R2 XE istifadə olunduğun görə dual virtual cədvəlindən select etməklə sequence-in qiymətini artırmaq məcburiyyəti var.

CLOB tipli məlumatın bazaya yazılması

Bu tipli məlumatı bazaya yazmaq üçün 2 variant var:

  • ASCII stream
  • Unicode character stream

Məlumatı ASCII stream kimi yazanda unikod hərfləri itir, çünki bu kodlaşdırma sistemində 1 hərf 1 bayt yer tutur, ə,ü,ç,ş,ı,ğ kimi milli hərflərimiz isə bu sistemdə yer almır.
Aşağıda CLOB məlumatını ASCII stream kimi yazmağa aid nümunə kod verilmişdir:

Connection con = ConnectionManager.getConnection();
con.setAutoCommit(false);
String sql = "update program_code set source=? where id=(select max(id) from program_code)";
PreparedStatement ps = con.prepareStatement(sql);
File file = new File("d:\\source.java");
// Use buffered input stream to optimize performance
BufferedInputStream  fin = new BufferedInputStream(new FileInputStream(file));
// Write CLOB as byte stream - unicode characters are lost
ps.setAsciiStream(1, fin, (int)file.length());
int rowCount = ps.executeUpdate();
con.commit();
System.out.println("Write CLOB is successfull. Row count = " + rowCount);
ConnectionManager.close(con);

FileInputStream source.java faylından məlumatı baytlar şəklində oxuyur. Bu fayla proyektdə yer alan ClobManager sinifinin kodlarını yazmışam. Unicode hərflərinin necə yazılacağını yoxlamaq üçün faylın əvvəlində şərh olaraq milli hərflərimizi yazmışam. CLOB məlumatını ASCII stream ilə yazdığımıza görə milli hərflərimiz bazaya səhv yazıldı. Aşağıdakı şəkildə bunu görmək olar.

Tərkibində unikod hərfləri olan məlumatı Character stream kimi yazmaq lazımdır, çünki bu halda milli hərflərimiz düzgün şəkildə baytlara çevrilib yazılır, məlumat itkisi baş vermir. Javada hərflər unikod kodlaşdırma sistemi ilə saxlanılır, ə,ü,ç,ş,ı,ğ kimi milli hərflərimiz bu sistemdə 2 bayt yer tutur.

Aşağıda CLOB məlumatını Unicode Character stream kimi yazmağa aid nümunə kod verilmişdir:

Connection con = ConnectionManager.getConnection();
con.setAutoCommit(false);
String sql = "update program_code set source=? where id=(select max(id) from program_code)";
PreparedStatement ps = con.prepareStatement(sql);
File file = new File("d:\\source.java");
// Use buffered reader to optimize performance
BufferedReader reader = new BufferedReader(new FileReader(file));
// Write CLOB as unicode character stream - unicode characters
ps.setCharacterStream(1, reader, (int)file.length());
int rowCount = ps.executeUpdate();
con.commit();
System.out.println("Write CLOB is successfull. Row count = " + rowCount);
ConnectionManager.close(con);

FileReader sinifi fayldan məlumatları unikod kodlaşdırma sistemi ilə oxuyur. CLOB məlumatını Unicode character stream ilə yazdığımıza görə bu dəfə milli hərflərimiz bazaya düzgün yazıldı. Növbəti şəkildə bunu aydın görmək mümkündür:

CLOB tipli məlumatın bazadan oxunması

Bu tipli məlumatı verilənlər bazasına yazmaq üçün 2 variant var:

  • ASCII stream
  • Unicode character stream

Məlumatı ASCII stream kimi yazanda unikod hərfləri itir, çünki bu kodlaşdırma sistemində 1 hərf 1 bayt yer tutur, ə,ü,ç,ş,ı,ğ kimi milli hərflərimiz isə bu sistemdə yer almır.
Aşağıda CLOB məlumatını ASCII stream kimi oxumağa aid nümunə kod verilmişdir:

Connection con = ConnectionManager.getConnection();
String sql = "select id, name, description, source from program_code where id=(select max(id) from program_code)";
String file = "d:\\clob.txt";
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
rs.next();
System.out.println("ID = " + rs.getLong(1));
System.out.println("Name = " + rs.getString(2));
System.out.println("Description = " + rs.getString(3));
// Use buffered input stream to optimize performance
BufferedInputStream bin = new BufferedInputStream(rs.getAsciiStream(4));
int character;
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(file));
while((character = bin.read()) != -1) {
 // Write clob data to file
 bout.write(character);
 // Write clob data to console
 System.out.print((char)character);
}
bout.close();
bin.close();
rs.close();
ConnectionManager.close(con);

Aşağıda CLOB məlumatını Unicode Character stream kimi oxumağa aid nümunə kod verilmişdir:

Connection con = ConnectionManager.getConnection();
String sql = "select id, name, description, source from program_code where id=(select max(id) from program_code";
String file = "d:\\clob.txt";
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
rs.next();
System.out.println("ID = " + rs.getLong(1));
System.out.println("Name = " + rs.getString(2));
System.out.println("Description = " + rs.getString(3));
// Use buffered input stream to optimize performance
BufferedReader reader = new BufferedReader(rs.getCharacterStream(4));
int character;
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
while((character = reader.read()) != -1) {
 // Write clob data to file
 writer.write(character);
 // Write clob data to console
 System.out.println(character);
}
writer.close();
reader.close();
rs.close();
ConnectionManager.close(con);

Burada oxuma və yazma əməliyyatlarının performansını artırmaq üçün FileReader obyekti BufferedReader ilə, FileWriter obyekti isə BufferedWriter obyekti ilə birgə istifadə olunmuşdur.

BLOB tipli məlumatı verilənlər bazasına yazmaq

BLOB tipli məlumat baytlardan ibarət olduğuna görə onu bazaya yazmaq üçün binary stream istifadə edilməlidir. Aşağıda BLOB məlumatını bazaya yazmağa aid nümunə kod verilmişdir:

Connection con = ConnectionManager.getConnection();
con.setAutoCommit(false);
String sql = "update program_code set image=? where id=(select max(id) from program_code)";
String file = "d:\\image.png";
PreparedStatement ps = con.prepareStatement(sql);
File file = new File(file);
// Use buffered input stream to optimize performance
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(file));
// Write BLOB as binary stream
ps.setBinaryStream(1, fin, (int) file.length());
int rowCount = ps.executeUpdate();
con.commit();
System.out.println("Write BLOB is successfull. Row count = " + rowCount);
ConnectionManager.close(con);

Burada BLOB tipli məlumat olaraq ekranın printscreen edərək d:\image.png faylına yazmışam, proqram isə həmin şəkli bazaya BLOB olaraq yazır.

BLOB tipli məlumatı verilənlər bazasından oxumaq

BLOB tipli məlumat baytlardan ibarət olduğuna görə onu bazadan oxumaq üçün binary stream istifadə edilməlidir. Aşağıda BLOB məlumatını bazaya yazmağa aid nümunə kod verilmişdir:

Connection con = ConnectionManager.getConnection();
String sql = "select id, name, description, image from program_code where id=(select max(id) from program_code)";
String file = "d:\\blob.png";
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
rs.next();
System.out.println("ID = " + rs.getLong(1));
System.out.println("Name = " + rs.getString(2));
System.out.println("Description = " + rs.getString(3));
// Use buffered input stream to optimize performance
BufferedInputStream bin = new BufferedInputStream(rs.getBinaryStream(4));
int character;
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(file));
while ((character = bin.read()) != -1) {
 // Write blob data to file
 bout.write(character);
}
System.out.println("BLOB data is written to " + file + " file");
bout.close();
bin.close();
rs.close();
ConnectionManager.close(con);

Bu proqramda isə bazadan oxuduğum BLOB tipli məlumat şəkildir, proqram həmin şəkli d:\blob.png faylına yazır.

Oracle SQL Developerdə həm CLOB həm də BLOB tipli məlumatları asanca görmək mümkündür.

Bizim nümunədə CLOB məlumat ClobManager.java proqram kodudur, onu görmək üçün aşağıdakı SQL sorğusunu işlədin

select * from program_code

Daha sonra source sütununa mouse ilə 2 dəfə vurun, redaktə rejiminə keçəcək və sağ tərəfdə qələm işarəsi çıxacaq. Həmin işarəyə vurduqda isə aşağıdakı şəkildəki kimi View value adlı pəncərə çıxacaq və onun daxilində ClobManager.java kodunu görmək olar.

BLOB tipli məlumatı görmək üçün də eyni qaydada qələm işarəsinə vururuq və açılan View Value pəncərəsinin aşağı hissəsində View as Image checkbox-unu seçməklə bazaya yazdığımız şəkli görə bilərik.

Proyekti  http://www.boxca.com/z27tv2jpcac0/LobManager.zip.html adresindən yükləyə bilərsiniz.

Suallarınız, təklif və tənqidləriniz üçün şərh yaza bilərsiniz. Ümid edirəm ki, faydalı oldu.

Qaynaqlar

1.Oracle® Database JDBC Developer’s Guide and Reference, 10g Release 2 (10.2) Part Number B14355-04

http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/oralob.htm#g1070326

2.Expert Oracle JDBC Programming

http://www.amazon.com/Expert-Oracle-JDBC-Programming-Menon/dp/159059407X

Tam Yazını Oxu | Make a Comment ( 10 so far )

Java proqramından Oracle bazasına SYSDBA olaraq qoşulmaq

Posted on 18 İyul 2010. Filed under: Java, JDBC, Oracle | Etiketlər: , , , , |

Java proqramında Oracle verilənlər bazasında SYSDBA sistem səlahiyyəti ilə qoşulmaq üçün DriverManager sinifinin overload edilmiş getConnection(String url, Properties prop) metodunu istifadə etmək lazımdır. Bu zaman istifadəçi adını, şifrəni və sysdba sistem səlahiyyətini(system privilege) Properties obyektində göstərmək lazımdır. Aşağıda buna aid sadə bir nümunə proqram kodu verilmişdir.

public class ConnectSysdba {

    public static void main(String[] args) throws Exception {
        String driver = "oracle.jdbc.Driver";
        String url = "jdbc:oracle:thin:@localhost:1521:XE";
        Connection con = null;

        // load jdbc driver
        Class.forName(driver);

        // connection info
        Properties info = new Properties();
        info.put("user", "sys");
        info.put("password", "oracle");
        info.put("internal_logon", "sysdba");

        // connect as sysdba
        con = DriverManager.getConnection(url, info);

        // check username
        String sql = "select user from dual";
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        rs.next();
        System.out.println("Username = " + rs.getString(1));
        rs.close();
        ps.close();
        con.close();
     }
 }
Tam Yazını Oxu | Make a Comment ( 2 so far )

OES (Oracle Errors&Solutions) proyekti haqqında

Posted on 14 İyul 2010. Filed under: Java, OES, Oracle, SQL | Etiketlər: , , , , , , , , |

Azərbaycanlı bir qrup Oracle administratorlar, proqramçılar və istifadəçilərin fərdi təşəbbüsü ilə birlikdə Oracle ilə bağlı open source proyekt hazırlamaq qərarına gəldik.Təklif professional Oracle DBA olan həmkarım Kamran Ağayevdən gəldi, mən də daxil olmaqla bir çox şəxslər tərəfindən dəstəkləndi. Məqsəd Oracle VBİS-nin rahat idarə olunmasına imkan verən proqram təminatı hazırlamaqdır. Toad, Oracle Enterprise Manager kimi ticari proqramların bütün funksionallıqlarını təkrarlamaq istəmirik, onlardan fərqli olaraq daha çox Oracle DBA-lər üçün spesifik gözəl imkanlar təqdim etməyi fikirləşirik(RMAN ilə backup və recovery işlərini asanlaşdırmaq və avtomatlaşdırmaq, Data guard qurmağı asanlaşdırmaq və s.) Kamranın bu barədə gözəl ideyaları var. Proyektin adına Azerbaijan Open Source Oracle Tool, qısaca AZOT olaraq qərar verdik, müzakirələrimi davam etdirmək üçün yeni qrup yaratdıq: http://groups.google.com/group/azot-az

İlk addım olaraq Oracle xətaları və onların həlli ilə bağlı məlumat bazası və axtarış sistemi qurmaq qərarına gəldik. Unix, Linux əməliyyat sistemlərində Oracle şirkəti OERR adlı utility təqdim edir. Bu proqram konsol rejimində işləyir və Oracle xətaları ilə bağlı məlumat əldə etməyə imkan verir. Belə bir proqramın bütün əməliyyat sistemlərində işləyən qrafik versiyasını hazırlamağa qərar verdik. Qrup daxilindəki müzakirələrdən sonra proyektin adını OES(Oracle Errors&Solutions) seçdik. İnternetə çıxışı olmayan kompüterdə belə bu proqramı istifadə etmək mümkün olsun deyə lokal axtarış üçün Oracle xətaları ilə bağlı məlumatları XML fayllarına yığdıq. XML fayllarının hazırlanmasına görə Zamir Camalova minnətdarlığımı bildirirəm.

OES proqramının hazırlanması ilə mən məşğul oldum. Bütün əməliyyat sistemlərində işləməsi üçün proqramı Java ilə yazdım. Proqramın görünüşü aşağıdakı kimidir:

Mümkün qədər open source proqram təminatı və texnologiyalardan istifadə etməyə çalışdım. Bu proyekt üçün aşağıdakı proqram təminatlarını istifadə etmişəm:

  1. Netbeans 6.7.1 – open source
  2. Notepad++ 5.5.1 – open source
  3. Apache Commons kitabxanaları – open source
  4. Stylus Studio 2010 XML Enterprise Suite – trial

Proqramı Netbeans İDE ilə yazdım. XML sənədləri ilə işləmək üçün Notepad++ istifadə etdim. Onu da qeyd edim ki, eyni XML fayllarını Netbeans-də açmağa çalışdım, Netbeans dondu qaldı, amma Notepad++ ilə eyni anda bir neçə XML faylını açıb rahat istifadə edirdim 🙂

Proqramın konfiqurasiya faylını rahat oxumaq üçün open source olan Apache Commons Configuration kitabxanasını istifadə etdim. Qeyd edim ki, bununla XML konfiqurasiya fayllarını və property fayllarını rahat şəkildə oxuyub istifadə etmək mümkündür.

Daha əvvəl də dediyim kimi lokal axtarış üçün XML faylları istifadə etdik. Proqramın cari versiyasında Oracle 10g R2, 11g R1 və 11g R2 üçün XML faylları mövcuddur, 8i, 9i R1, 9i R2, 10g R1 versiyaları üçün XML faylları hazır olanda proqrama əlavə ediləcək. Bu versiyada ancaq ORA-XXXXX xətaları ilə bağlı məlumat mövcuddur, amma versiyada RMAN, import və export xətalarını da əlavə etməyi planlaşdırırıq. XML fayllarında axtarış üçün SAX modelini istifadə etdim, çünki faylların ölçüsü böyük olduğuna görə (1 fayl təxmini 3-4 MB-dır) onun DOM modeli yaddaşda çox yer tutacaq. Mənə verilmiş XML fayllarının ilkin strukturu aşağıdakı kimi idi:

<OraCode>
	<row>
		<code>ORA-38029: object statistics are locked</code>
		<cause>An attempt was made to modify optimizer statistics of the
        object.

        Action</cause>
		<action>Unlock statistics with the DBMS_STATS.UNLOCK_TABLE_STATS
        procedure on base table(s). Retry the operation if it is okay to
        update statistics.</action>
	</row>
	<row>
		<code>ORA-38101: Invalid column in the INSERT VALUES Clause: string</code>
		<cause>INSERT VALUES clause refers to the destination table
        columns

        Action</cause>
		<action>None</action>
	</row>
</OraCode>

SAX modelinə əsasən XML faylını parse etmək və konkret bir Oracle xətasının koduna görə sürətli axtarış etmək üçün XML fayllarını aşağıdakı formata çevirmək qərarına gəldim.

<oracle-errors>
	<metadata>
		<version>Oracle database version</version>
		<prepared-by>Author</prepared-by>
		<last-update-date>Update timestamp</last-update-date>
		<language>English</language>
	</metadata>
	<error-list>
		<error id="ORA-00000">
			<code>ORA-00000: normal, successful completion</code>
			<cause>Normal exit.</cause>
			<action>None</action>
		</error>
		<error id="ORA-00001">
			<code>ORA-00001: unique constraint (string.string) violated</code>
			<cause>An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode, you may see this message if a duplicate entry exists at a different level.</cause>
			<action>Either remove the unique restriction or do not insert the key.</action>
		</error>
	</error-list>
</oracle-errors>

Metadata elementi XML faylı haqqında məlumatı göstərir. Xəta kodunu isə error elementinə atribut olaraq əlavə etdim.
XML çevrilməsini reallaşdırmaq üçün XSL və XSLT tətbiq etdim. XSL Extensible Style Sheets, XSLT isə XSL Transformation deməkdir. XSL faylında original XML formatından lazım olan XML formatına çevrilmələr üçün qaydaları yazdım. Hazırladığım XSL faylı aşağıdakı kimidir:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
	<oracle-errors>
		<metadata>
			<version>Oracle database version</version>
			<prepared-by>Author</prepared-by>
			<last-update-date>Last update timestamp</last-update-date>
			<language>English</language>
		</metadata>
		<error-list>
			<xsl:for-each select="OraCode/row">
				<error>
			<xsl:variable name="errorCode" select="substring(code, 1, 9)"></xsl:variable>
					<xsl:attribute name="id">
						<xsl:value-of select="$errorCode"/>
					</xsl:attribute>

			<xsl:variable name="code" select="normalize-space(code)"></xsl:variable>
					<code>
						<xsl:value-of select="$code"></xsl:value-of>
					</code>

		<xsl:variable name="cause" select="normalize-space(cause)"></xsl:variable>
					<cause>
						<xsl:choose>
							<xsl:when test="contains($cause, ' Action')">
								<xsl:value-of select="substring-before($cause, ' Action')"></xsl:value-of>
							</xsl:when>
							<xsl:otherwise>
								<xsl:value-of select="$cause"></xsl:value-of>
							</xsl:otherwise>
						</xsl:choose>
					</cause>

					<xsl:variable name="action" select="normalize-space(action)"></xsl:variable>
				    <action>
						<xsl:value-of select="$action"></xsl:value-of>
					</action>
				</error>
			</xsl:for-each>
		</error-list>
	</oracle-errors>
</xsl:template>

</xsl:stylesheet>

ORA-XXXXX formatında olan kodu <code> elementindən aşağıdakı kimi əldə etmək olar

<xsl:variable name="errorCode" select="substring(code, 1, 9)"></xsl:variable> 

Lazımsız boşluqları təmizləmək üçün normalize-space funksiyasını istifadə etdim.

Oracle 10g R2 üçün olan XML faylında <cause> elementinin sonunda artıq olan Action sözünü aşağıdakı kimi təmizlədim, digər fayllarda belə problem yoxdur.

<xsl:variable name="cause" select="normalize-space(cause)"></xsl:variable>
<xsl:choose>
 <xsl:when test="contains($cause, ' Action')">
 <xsl:value-of select="substring-before($cause, ' Action')"></xsl:value-of>
 </xsl:when>
 <xsl:otherwise>
 <xsl:value-of select="$cause"></xsl:value-of>
 </xsl:otherwise>
 </xsl:choose>

Bu XSL faylını hazırlamaq və test etmək üçün “Stylus Studio 2010 XML Enterprise Suite” proqramının trial versisını yüklədim. Əvvəlki iş yerimdə XML ilə bağlı bir məsələ üçün bu proqramı istifadə etmişdim və çox razı qalmışdım. Belə imkanlara malik open source proqram tapmadığıma görə trial versiyanı istifadə etdim. “Stylus Studio 2010 XML Enterprise Suite” həqiqətən də XML texnologiyaları ilə işləmək üçün güclü imkanlara malik olan bir professional proqramdır.

XSL faylı hazır olduqdan sonra isə XSTL faylları yeni formata çevirmək qalır. Bunun üçün Transformer adlı kiçik bir Java proqramı yazdım və Javada olan standart JAXP APİ ilə çevirməni elədim. Transformer proqramının kodu 1 Java sinifindən ibarətdir və aşağıdakı kimidir:


package transformer;

import java.io.File;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Main {
    public static void main(String[] args) {
      if (args.length != 3) {
        System.out.println("Usage: transformer.Main error.xml transform.xsl result.xml");
      } else {
        try {
          StreamSource xml = new StreamSource(new File(args[0]));
          StreamSource xsl = new StreamSource(new File(args[1]));
          StreamResult result = new StreamResult(new File(args[2]));
          TransformerFactory factory = TransformerFactory.newInstance();
          Transformer t = factory.newTransformer(xsl);
          t.setOutputProperty(OutputKeys.INDENT, "yes");
          t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "8");
          t.transform(xml, result);
       } catch (Exception ex) {
          System.out.println("Error occured during transformation: " + ex.getMessage());
          ex.printStackTrace();
       }
     }
   }
}

Transformer proqramını və Java kodunu buradan yükləyə bilərsiniz: http://www.boxca.com/mju16j6r5ero/Transformer.zip.html

Yeni formatda XML faylları hazır olduqdan sonra onları OES proqramında SAX modeli ilə parse edib istifadəçinin daxil etdiyi xəta kodunu axtardım. XML sənədlərini SAX modeli ilə parse etmək haqqında ayrıca bir yazı hazırlamağı fikirləşirəm, bu barədə orada ətraflı izah verəcəm.

Onlayn axtarış üçün Google və Oracle forumları istifadə olunur. Bu axtarış mexanizmi sadədir, istifadəçi axtardığı koda uyğun nəticələr səhifəsinə yönləndirilir.

Google-da axtarış etmək üçün http://www.google.az/search?q=ORA-XXXXX,  Oracle forumlarında axtarış etmək üçün isə http://forums.oracle.com/forums/search.jspa?q=ORA-XXXXX adresi istifadə olunur. Buradakı XXXXX Oracle xəta kodunun nömrəsini göstərir(məsələn ORA-00001).

Qrupun fayllar bölməsində proqramın ümumi və texniki dokumentasiyasını, XML sənədlərinin strukturunu, XSL faylını və transformer proqramını əldə etmək mümkündür.
Proqramın son versiyasını bu linkdən yükləyib test edə bilərsiniz: http://www.boxca.com/hgso43gyboye/OES_1.1.zip.html
Proyektin kodlarını daha sonra code.google.com-da yerləşdirib, linkini bura qoyacam.

Tam Yazını Oxu | Make a Comment ( 1 so far )

« Əvvəlki yazılar

    Haqqında

    Java ilə obyekt yönlü proqramlaşdırma, Java web proqramlaşdırma, Oracle SQL, PL/SQL proqramlaşdırma, optimallaşdırma

    RSS

    Subscribe Via RSS

    • Subscribe with Bloglines
    • Add your feed to Newsburst from CNET News.com
    • Subscribe in Google Reader
    • Add to My Yahoo!
    • Subscribe in NewsGator Online
    • The latest comments to all posts in RSS

    Meta

Liked it here?
Why not try sites on the blogroll...