Oracle'da Silinen Tabloyu Geri Getirmek

by Suat TUNCER 31. July 2009 12:24

Bir veritabanı nesnesini yanlışlıkla sildiğinizi düşünün, bunun farkına fardığınız ilk beş saniye ağzınız açık gözleriniz irice açılmış bir şekilde ekrana bakakalırsınız. Ardından geçen iki saniye de okkalı bir ha...tir çekersiniz acı bir nidayla. Ardından içerdiği dataları düşünür, müşteriyi düşünür sonrada oluk oluk terlemeye başlarsınız. Ama bu durum Oracle'da başınıza geldiyse bu kadar sıkıntı yapmaya gerek yok, oldukça kolay bir şekilde geri alabilirsiniz. Silinen nesneler DBA_RECYCLEBIN ve USER_RECYCLEBIN tablolarında tutular, burayı sorgulayarak korkularımızla yüzleşiriz.

SELECT OBJECT_NAME, ORIGINAL_NAME FROM USER_RECYCLEBIN sorgusunu çalıştırdığınızda ORIGINAL_NAME sütününde sildiğiniz nesnenin adını görüyorsanız rahat bir nefes alın artık :).

Nesnenizin yanında bulunan OBJECT_NAME değerini aşağıdaki gibi sorulayıp datalarınızı görebilirsiniz.

SELECT * FROM "BIN$b/yFhnhEQCzgQ6wWAQtALA==$0"

tablonuzu geri almak için FLASHBACK TABLE [tablo_adi] TO BEFORE DROP sorgusunu çalıştırdığınızda tablonuz ve datalarınız geri gelecektir.

 

Hadi geçmiş olsun.

Tags: , , ,

Database

NHibernate ve Performans

by Suat TUNCER 31. October 2008 21:05

     Çok uzun olmamakla beraber bir süredir proje geliştiriken NHibernate kullanıyorum. Aslında oldukça pratik bir tool. Özellikle nesnelerin rahatlığını size sunduğu için odağınızı neredeyse tamamen uygulama katmanına kaydırıyor, buda daha kaliteli, okunabilir ve yüksek oranda object oriented bir kodun orataya çıkmasını sağlıyor.

     Yaşadığım bir kaç sıkıntıyı paylaşmak isterim. Create, Update ve Delete işlemlerinde oldukça hızlı ve sorunsuz çalışmasına rağmen sorgulama özellikle de raporlamada çok ciddi performans sıkıntıları var, tabi burada problem birazda benim raporlama kaynağı olarakta object collectionlar kullanmak istememden kaynaklanıyor.

     Tavsiyem sorgulamada HQL veya SQL kullanılmasından yanadır özellikle complex raporlama tarzı sorgularda kesinlikle IQuery interfacesi kullanılmalı ICriteria değil. Benim tercihim HQL hernekadar SQL tarzı sıkıcı sorgular yazmak zorunda kalsamda nesne sorguladığım için daha keyifli ve kullanışlı. Gönül isterdiki LINQ ile NHibnernate kardeş kardeş çalışsın mamhif henüz mümkün değil.

 

// Sorgu Cümlesi hazırlanıyor, SQL cümlesi gibi düşünülebilir
// farkı tablolar herine tipler var
StringBuilder hql = new StringBuilder();
hql.Append("from HighCode.Domain.Content as content ");
hql.Append("where content.ContentType=:type");

// hql cümlesi kullanılarak bir IQuery nesnesi oluşturulur
IQuery query = _session.CreateQuery(hql.ToString());

// parametre eklenir
query.SetParameter("type", ContentType.Article);

// sorgu çalıştırılır
IList<Content> result = query.List<Content>();

Tags: , ,

Database | O/RM Tools

DataTable Üzerinde Distinct ve GroupBy

by Suat TUNCER 31. October 2006 19:16
        Merhaba, T-SQL'de yer alan Distinct fonksiyonu ve Group By clause'unu birçok defa kullanmışızdır, ne iş yaptıklarıda malum yinede şurdan buradan bakılabilir,
        Dönelim konumuza sorun şuki DataTable'e çekilen veriler üzerinde bu fonksiyonları uygulamak hazır fonksiyonlarlar mümkündeğil ve .Net Framework ne yazıkki bu konuda hazır bir fonksiyon içermediği için iş başa düştü, kendi faonksiyonumu hazdım buraya ekliyorum, kullanabilirsiniz

 

        Şimdi bu fonksiyon ne iş yapar; Diyelimki veritabanından verilerimizi çekmişiz ama öyle bir select sorgusuyla değil, iç içe sorgular, fonksiyonlar, hesaplamalarla çekmişiz. Bu titiz çalışmanın sonucu elimizde sadece bir tablo var fekat biz bu tablo üzerinde bir daha çalışmak istiyoruz. Örneğin verileri bir daha gruplamak istiyoruz fakat bunu T-SQL ile yapamıyoruz çünkü yazdığımız sorgu buna izin vermiyor. Çok abartı bir örnek oldu değilmi, yok yok hiçte öyle olmadı,değil çünkü, aynı böyle bir durumla karşılaştım bugün ve oturdum böyle bir fonksiyon yazdım.

public class SharpSql
{
    public SharpSql(){}

    public DataTable Distinct(DataTable dataSource,
                                 string distinctColumn)
    {
        DataTable returnTable=new DataTable("distinctTable");
        /*
         * kaynak tablodaki sütunları
         * geri dönecek tabloya kopyalıyorum
         * böylece direkt satır eklenirken
         * sütunların birebir eşleşmesini sağlıyorum
         */
        foreach(DataColumn c in dataSource.Columns)
        {
            returnTable.Columns.Add(c.ColumnName,c.DataType);
        }
        bool hasRow=false;
        foreach(DataRow selectedRow in dataSource.Rows)
        {
            /*
             * kaynak tabloda herbir satırı seçip
             * sonuçların bulunduğu tabloda benzerinin
             * olup olmadığına bakıyorum
             */
            foreach(DataRow r in returnTable.Rows)
            {
                /*
                 * eşleşen sonuçlar bulunursa,
                 * satırın var olduğu anlamında
                 * hasRow=true yapıyorum
                 */
                if(r[distinctColumn].ToString() ==
                    selectedRow[distinctColumn].ToString())
                {
                    hasRow=true;
                    break;
                }
            }
            /*
             * Seçili satır bulunmamışsa hasRow değeri
             * varsayılan olarak false olacağı için,
             * satır ekleniyor
             */
            if(hasRow==false)
                returnTable.Rows.Add(selectedRow.ItemArray);
            hasRow=false;
        }
        return returnTable;
    }
    /*
     * her bir sütunun kendi toplamına ihtiyacım vardı
     * ve normal DataColumn'da böyle bir değer yoktu
     * bir class oluşturup inherit ettikten sonra
     * Toplam property'sini ekledim
     */
    public class GroupColumn:System.Data.DataColumn 
    {
        private double dblToplam;
        public GroupColumn(string columnName)
        { this.ColumnName=columnName; }

        public double Toplam
        {
            get{return dblToplam;}
            set{dblToplam=value;}
        } 
    }
    /*
     * ve yine tip dönüşümlerinde normal DataColumnCollection,
     * inherits edilmiş GroupColumn classında
     * tip dönüşüm hatası verdiğinden bunun yerine
     * kendi GroupColumnCollections'ımı yazdım 
     */
 
    public class GroupColumnCollection:CollectionBase 
    {
        public GroupColumnCollection(){}
        public void Add(GroupColumn obj)
        { this.InnerList.Add(obj);} 
    }

    public DataTable GroupBy(DataTable dataSource,
                     GroupColumnCollection columns,
                                 string groupByColumn)
    {
        /*
         * Gruplanırken, unique kolonlara göre
         * istenilen toplamlar alınıyor
         * Unique(benzersiz) sütunlar yazdığım
         * Distinct fonksiyonu ile eldeediliyor
         */
        DataTable tableDistinct;
        tableDistinct=this.Distinct(dataSource,groupByColumn);
        /*
         * dataview kullanılıyorki her bir 
         * groubBy kolonuna göre 
         * ayrı ayrı sonuçlar alınsın diye
         */
        DataView viewResult=new DataView();
        viewResult.Table=dataSource;
        DataTable returnTable=new DataTable("groupTable");
        DataRow returnRow;
        //Sütünlar ekleniyor
        foreach(GroupColumn c in columns)
        {
            returnTable.Columns.Add(c.ColumnName,c.DataType);
        }
        //Adet sütünü ekleniyor
        returnTable.Columns.Add("Adet");
        //Gruplamada kullanılan sütunu ekliyorum
        returnTable.Columns.Add(groupByColumn);
        //Toplamları hesaplayp ekliyorum
        foreach(DataRow r in tableDistinct.Rows)
        {
            viewResult.RowFilter =groupByColumn + " = '" 
                        + r[groupByColumn].ToString() + "'";
            //Yeni bir satır oluşturuyorum
            returnRow = returnTable.NewRow();
            /*
             * dataviewe rowfilter uygulandıktan sonra 
             * kalan satırlar geziliyor ve 
             * toplamları hesaplayıp
             * değerleri yeni satıra atıyorum
             */
            for(int  i=0;

                        i<=viewResult.Count;

                        i++)
            {
                foreach(GroupColumn c in columns)
                {
                    c.Toplam += Convert.ToDouble(viewResult[i][c.ColumnName]);
                    returnRow[c.ColumnName]=c.Toplam;
                }
            }
            //Grup adı ve adetini ekliyorum
            returnRow[groupByColumn]=r[groupByColumn].ToString();
            returnRow["Adet"]=viewResult.Count;
            //Son olarak satırı tabloya ekliyorum
            returnTable.Rows.Add(returnRow);
        }
        return returnTable;
    }
}


        Bu kadar yazdıktan sonra hadi ne haliniz varsa görün demiycem elbette, şimdi bunu örnek bir uygulamada kullanarak ne işe yaradığını tam olarak anlatayım, Yeni bir WindowsApplication projesi açıp, yukardaki Classımızı orya ekliyelim, ardında forma 2 DataGrid 3 adette button ekleyip aşşağıdaki kodları yazıyoruz,


 

/

/yukardaki classtan bir instance oluşturuyorum
SharpSql csSql=new SharpSql();

//verileri getir butonu
private void button1_Click(object sender, System.EventArgs e)
{
    SqlConnection cn=new SqlConnection(
                "Data Source=.;
                 Initial Catalog=Northwind;
                 Integrated Security=SSPI;"
);
    SqlCommand cmd=new SqlCommand("select * from [Order Details]",cn);
    SqlDataAdapter da=new SqlDataAdapter(cmd);
    DataSet ds=new DataSet();
    da.Fill(ds,"siparisDetay");
    dataGrid1.DataSource=ds.Tables[0];
}

//Distinct butonu

private void button2_Click(object sender, System.EventArgs e)
{
    /*
     * tekrar eden kayıtlar eleniyor

     * ve sonuç bir DataTable olarak döndüğü için
     * DataSet'e ekliyorum
     */
    string distinctColumn;
    distinctColumn=((DataTable)dataGrid1.DataSource).Columns[dataGrid1.CurrentCell.ColumnNumber].ColumnName ;
    dataGrid2.DataSource=csSql.Distinct((DataTable)dataGrid1.DataSource ,distinctColumn);
}

//Group By butonu

private
void button3_Click(object sender, System.EventArgs e)
{
    /* 
     * Gruplandırmada kullanılacak sütun ve 
     * toplamların alınacağı sütunları ekliyorum
     * sonuç yine datatable olarak döndüğünden
     * onuda dataset'e ekliyorum
     */
    SharpSql.GroupColumnCollection col=new SharpSql.GroupColumnCollection();
    SharpSql.GroupColumn obj;
    obj=new SharpSql.GroupColumn("UnitPrice");
    col.Add(obj);
    obj=new SharpSql.GroupColumn("Quantity");
    col.Add(obj);                
    string groupColumn;
    groupColumn=((DataTable)dataGrid1.DataSource).Columns[dataGrid1.CurrentCell.ColumnNumber].ColumnName;
    dataGrid2.DataSource=csSql.GroupBy((DataTable)dataGrid1.DataSource,col,groupColumn);
}


        Programı çalıştırdığımızda öncelikle Verileri Getir butonunu tıklıyoruz gelen veriler sadece select sorgumusun sonuçları, ProductID sütununa göre sıralayınca anlaşılacaktır zaten, ProductID stünunu seçip Distinct butonuna tıklayınca sonuçlar dataGrid2'de görünecektir tekrar edilen satırlar elendi


    Group By butonuna tıladığımızda ise bu defata, kodlarımızda belirttiğimiz Quantity ve UnitPrice sütunlarındaki değerlerin ProductID'ye göre toplamları görünecektir




       Benimde en çok ihtiyaç duyduğum kısım GroupBy kısmıydı ve bu işimi oldukça gördü umarım sizlerinde işine yarar (biraz uzun oldu sanki Foot in mouth )

 

 

 

Tags: , , ,

C# | Database