Buradaki soru da çok güzel cevabı da paylaşmak istedim ,

http://forums.oracle.com/forums/thread.jspa?messageID=1383006

I have seen this question a couple of time on the net over the last little while. I posted the answer below, and thought I might as well put it on the blog as well. The thread continued on after the initial question to include a bunch of more detail that made my answer not the correct answer. I guess I should have simply asked “Why” instead of trying to figure out what the person really wanted.

Unfortunately I have had to do this in the past:

Don’t drop your table of course, but I wanted this to be complete:

0
1
2
3
4
5
6
7
8
9
DROP TABLE REORDER;
 
CREATE TABLE REORDER
(COLUMN4 NUMBER
,COLUMN3 NUMBER
,COLUMN2 NUMBER
,COLUMN5 NUMBER
,COLUMN1 NUMBER
,COLUMN6 NUMBER
);

Now if you select it the columns come up in the order it was created

0
SELECT * FROM REORDER;

You can simply select the columns in the order you want:

0
SELECT COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5,COLUMN6 FROM REORDER;

You can create a view that the users can use if you wish:

0
CREATE OR REPLACE VIEW ORDERED_REORDER AS SELECT COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5,COLUMN6 FROM REORDER;
0
SELECT * FROM ORDERED_REORDER;

clean up

0
DROP VIEW ORDERED_REORDER;

I have done this on SMALLER tables less than a few thousand with 100 million+ rows, I wouldn’t do this without some thorough testing.

change the name of the table

0
RENAME REORDER TO ORIG_REORDER;

create a view to look like the original table

0
CREATE VIEW REORDER AS SELECT COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5,COLUMN6 FROM ORIG_REORDER;

Now the view looks the way you want:

0
SELECT * FROM REORDER;

You can insert etc:

0
1
2
INSERT INTO REORDER (COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5,COLUMN6)
VALUES (1,2,3,4,5,6);
COMMIT;

Some apps won’t allow this, they need tables and won’t allow views.
Test test test. But first, I would suggest getting a good business case for this as this is an oddball request. Those requests do exist but get it in writing and see if there isn’t a better way to handle the request.

Oracle için kullandığım ve geliştirmekte olduğum PHP ORM kütüphanemde kompleks sorgulara girdikçe yeteneklerini arttırmam gerektiğini farkettim, veritabanını düşünmeden ORDER BY parametresine bir SUBQUERY yazdım düz mantıkla bu kesinlikle performans kaybıdır diye düşünerek Plan analizi yaptırdım veritabanına ama sonuç beni şaşırttı ve  yeni birşey öğrendim (: ORDER BY için bir subquery kullanmak JOIN den daha hızlıymış (: hemen bir örnek vermek istiyorum

Futbolcuları Takımları ile eşleştirip takım adına göre dizmek istedim.

0
1
SQL > SELECT P.NAME,P.ID  FROM PLAYERS P JOIN CLUBS C ON P.CLUB_ID = C.ID
ORDER BY C.NAME;

bunu kütüphanem yazamazdı ben de ORDER BY kısmına query yazdım ve sorgum bu hale geldi.

0
1
SQL > SELECTNAME,ID FROM PLAYERS P
ORDER BY (SELECT NAME FROM CLUBSC WHERE C.ID = P.CLUB_ID);

ve Plan analizinin sonucu (:
JOIN

0
1
2
3
4
5
6
7
8
Operation
------------------------------
SELECT STATEMENT
 SORT ORDER BY
  MERGE JOIN
   TABLE ACCESS BY INDEX ROWID
    INDEX FULL SCAN
   SORT JOIN
    TABLE ACCESS FULL

SUBQUERY

0
1
2
3
4
5
6
Operation
----------------------------
SELECT STATEMENT
 TABLE ACCESS BY INDEX ROWID
  INDEX UNIQUE SCAN
 SORT ORDER BY
  TABLE ACCESS FULL

Tuning fantazilerine girerseniz aklınızda bulunsun (: iyi çalışmalar,

OCI-Lob  sınıfını tanımıştık. bu sınıfın insert ve update  sorguları için kullanılan metodu olan OCI-Lob::save()  metodunu inceliyor olacağız.  Update sorgularımız için şartımıza uyan bir satır  yoksa php OCI_INVALID_HANDLE gibi bir hata fırlatıyor. update işlemlerini bir sonraki yazıda işleyeceğimiz için şimdilik sadece bahsedip geçiyoruz.

OCI-Lob
bool save ( string $data [, int $offset ] )

save metodu LOB alanlara veri yazmak için kullanılır. OCI lob objelerinin indikasyon özelliği olduğundan  opsiyonel olarak  offset değeri de verebiliyoruz . yani istersek veriyi  lobun istediğimiz alanına yazabiliyoruz.

işte örnek insert işlemi.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$conn=oci_connect(); // bağlantı ayarlarınız
 
$sql = "INSERT INTO loblar
          (
            id,
            lobalan
          )
       VALUES
          (
            loblar_seq.NEXTVAL,
            -- Boş bir CLOB oluşturuyoruz
            EMPTY_CLOB()
          )
       RETURNING
          -- Lob locator dönderiyoruz
          lobalan INTO :mylob_loc";
 
$stmt = oci_parse($conn, $sql);
 
// Boş bir OCI-Lob objesi oluşturuyoruz
$myLOB = oci_new_descriptor($conn, OCI_D_LOB);
 
// LOB loactor a bağlıyoruz.
oci_bind_by_name($stmt, ":mylob_loc", $myLOB, -1, OCI_B_CLOB);
 
// Sorguyu çalıştıyoruz (Default Transaction modunda)
oci_execute($stmt, OCI_DEFAULT)
    or die ("Unable to execute query\n");
 
//  Lob alana şimdi istediğimizi yazdırıyoruz
if ( !$myLOB->save('Tarih : '.date('H:i:s',time())) ) {
 
    // Hata olmuşsa geri sarıyoruz
    oci_rollback($conn);
 
} else {
 
    // başarıyla yazabildiysek commit ediyoruz.
    oci_commit($conn);
 
}
 
// kaynakları boşaltıp  veritabanı bağlantısını kesiyoruz.
oci_free_statement($stmt);
$myLOB->free();
oci_close($conn)

Blob Compression konusunda bilgi almak için de şu konuyu okuyabilirsiniz

Oracle Blob Compression

4000 byte’tan daha büyük verilerle çalışıyorsak LOB  alanlara ihtiyacımız olacaktır.   

Standart (basit) veritabanı tipleriyle çalışmak diğer datalarda olduğu gibi Oracle’da da oldukça kolay. Fakat dosya saklama – ya da stringe dönüşümünde veri bozulmaları yaşayabileceğimiz 4000 byte tan büyük datalarla çalışacaksak Oralce LOB (Long Objects) lara ihtiyacımız olacaktır. PHP ile Oracle LOB alanlarda  yapabileceğimiz işlemleri incelemden once kısaca LOB tipleri tanımlayalım  

Oracle LOB Objects     

 

  • BLOB, Binary verileri saklamak için kullanırır (Binary Long Object)
  • CLOB, Veritabanı karakter setinde normal karakterler saklamak için kullanılır (Characters Long Object)
  • NCLOB,Unicode datalar saklamak için kullanılır . PHP nin Oci8 eklentisinde bu yoktur.
  • BFILE, Veritabanı sunucusnda dosya adresini referans alarak sunucuda saklanacak dosyalar için kullanılır.
  •   

    Üzerinde işlem yapılan LOB alanlar biz boşaltana kadar geçici tablo alanında (Temporary Tablespace) saklanır .  Oracle 9i ve öncesinde bu tipler için table spacede ayrı ayrı saklama yeri oluşturuluyormuş bu yuzden eski sürümlerde bu tipler üzerinde işlem yaparken daha dikkatli olmamız söyleniyor.   

     LOB Saklama 
    Oracle 10g  her LOB hücresi için 128 TB kadar veri saklama kapasitesine sahipmiş. Bu Veri tabanı block boyutu ve yığınlama ayarlarında isteğe bağlı değiştirilebiliniyormuş.  LOB verilerinin saklanması 2 elemanla olur. LOB Content  ve LOB Locator. LOB Content   sadece LOB Locator’un adresini içerir. 
          Dahili LOB tipleri (BFILE dışında kalanlar) 4KB nin altında  olduğu sürece diğer tablo verileriyle aynı (stored in line in the table ) yerde saklanır.   lob alanlarınız 4 kb den küçükse isteklerinizin işlenip size gelmesi gayet hızlı olacaktır. fakat büyükse bu  tablo için yapılan SELECT sorgularında LOB sütunlarının dahil edilmesi sorgu sonucu almanızı yavaşlatacaktır.  

    LOB Kısıtlamaları  
     Lob alalar için en önemli kısıtlamalar. Sorgu dahilinde sıralama ve gruplama işlemleridir.  

    • Coğul Elemelerde  kullanılmaz
    • Sıralamalarda kullanılamaz
    • Gruplamalarda kullanulamaz
    • Birleştirmelede kullanılamaz
    • Primary Key olarak atanamaz
    • Unique index oluşturulamaz

    SELECT DISTINCT <lob_type>
    ORDER BY <lob_type>
    GROUP BY <lob_col>   

    dahil edemeyeceğimiz bu işlemler ile yine bu işlemleri kullanan  UNION -MINUS -INTERSECTION gibi tablo birleştirme işlemlerinide kısıtlamış olur.  

    PHP ve ORACLE LOB işlemleri (OCI-Lob Sınıfı):
       Bu sınıfla ilgili php manual de  maalesef cok sınıflı bilgi var.  php ile OCI LOB işlemleri yapmamız için kullanabileceğimiz bu sınıf dikkatimi çektiği üzere bir cok PHP IDE tarafından da complatorlara dahil edilmemiş.! 

    Yerel Sunucumda PHP 5.3 versiyonunda OCI-Lob sınıfının metodlarını incelemek istedim.
      

    OCI-Lob::load()          
    OCI-Lob::tell()          
    OCI-Lob::truncate()      
    OCI-Lob::erase()         
    OCI-Lob::flush()         
    OCI-Lob::setbuffering()  
    OCI-Lob::getbuffering()  
    OCI-Lob::rewind()        
    OCI-Lob::read()          
    OCI-Lob::eof()           
    OCI-Lob::seek()          
    OCI-Lob::write()         
    OCI-Lob::append()        
    OCI-Lob::size()          
    OCI-Lob::writetofile()   
    OCI-Lob::export()        
    OCI-Lob::import()        
    OCI-Lob::writetemporary()
    OCI-Lob::close()         
    OCI-Lob::save()          
    OCI-Lob::savefile()      
    OCI-Lob::free()           

    metodların hepsini maalesef işleyemeyeceğim fakat kullandıkça örnekleri de buraya yazmaya çalışacağım. 

    © 2012 Tufan Suffusion theme by Sayontan Sinha