pl/sql etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
pl/sql etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

24 Eylül 2007

And Operatörü ile Sorgulama

Veritabanı sorgulamalarında and ifadelerine sahip cümle grubunda 1. şartın sağlanmaması durumunda diğer şartlar kontrol edilmez. Bu durumda and ifadesi öğelerinde en hızlı çalışacak koşulu önce yazmak bize performans kazancı sağlayacaktır.

Örnek verecek olursak;

Bazı durumlarda bir değerin bulunan kayıta göre iki farklı alandan alındığı durumlar olabilmekte. Örneğin müşteri tablomuzda name,surname ve firmname isimli alanlar olsun.
Name ve surname alanları boşsa müşteri ismi firmname kolonundan alınsın.

Eğer biz A ile başlayan müşterileri sorgulamak istersek;

(name like 'A%' and firmname is null) or (firmname like 'A%' and name is null)

şeklinde yazabildiğimiz sorguyu ;

(firmname is null and name like 'A%' ) or (name is null and firmname like 'A%')

şeklinde yazarsak daha performanslı çalışır. Performans kazancı koşulların çok olduğu cümlelerde artacaktır.

17 Eylül 2007

Oracle'da Triggerlar

Sql Server'da triggerlar sadece işlem yapıldıktan sonra çalışır.

Oracle'da BEFORE ve AFTER ek komutlarıyla triggerların tetikleme işleminden önce veya sonra olmasına karar verebiliriz.



Bu ek komutlar da iki durumda kullanılabilir.
İşlem bazında BEFORE ve AFTER ek komutları uygulanabilir.
Satır bazında BEFORE ve AFTER ek komutları uygulanabilir.

CREATE TRIGGER trigger_ismi
BEFORE DELETE OR INSERT OR UPDATE
ON tablo_ismi
{pl/sql kod bloğu}

25 Ağustos 2007

Veritabanı Tarafında Sayfalama (Paging)

Raporlama modüllerinde eğer sayfalamayı grid tarzı bir kontrole bırakmıyorsak aşağıdaki sorguları kullanarak verdiğimiz aralıktaki kayıtları çekebiliriz.Oracle'da daha önce var olan yapı Sql Server 2005 birlikte Sql server kullanıcıları için de eklendi.

Oracle için;

select * from (
select rownum rnum from (
select * from table
) t1
) where rnum between 101 and 200


Sql Server 2005 için (AdwentureWorks veritabanını kullandık)

select AddressLine1,City, ModifiedDate
from (select AddressLine1,City,ModifiedDate,row_number() over (order by
ModifiedDate desc)
as rnum from Person.Address) as RnumAdress
where rnum >= 101 and rnum <= 200

Fakat bu yapıların tek dezavantajı raporlama anında kayıt değişiklikleridir.
Örnek verecek olursak;
Sitede bir panelde online 100 kişi 10'arlı sayfalar halinde siteye giriş sırasına göre gösteriliyor. Eğer bu gezinme esnasında siteye yeni kişiler girerse bu kayıtlarda kaymalar olacaktır. Sayfalarda ilerlemeye devam ettikçe bir önceki sayfanın sonundaki kayıtların bir sonraki sayfanın ilk kayıtları olarak eklendiğini görürüz. Genellikle bu çok da zararlı olmayan durum performansı etkileyecek diğer yöntemlere tercih edilmektedir.

16 Ağustos 2007

Where Kosulunu Devre Dışı Bırakmak

Blog yazılarımda karşılaşıp bulduğum bazı küçük çözümleri yazmaya çalışıyorum. Ne yazık ki klasik problemlerle ilgili bir çok sonuç bulabilirken çok özel durumlar için bilgi bulmak biraz zor oluyor.

Bir listeleme kontrolünüz olsun. (Treeview, Combo, Listbox ..).
Bu kontrolün elemanları bir sorguyla dolsun ve seçilen elemanın değerini başka bir listelemede kullanalım.

Örneğin ismin ilk harfine göre listeleme olsun ve hangi harf seçilirse diğer listede bu harfle ilgili bir içerik gelsin.

İlk listeyi aşağıdaki sorguyla dolduralım.

select 'A','A'
union select 'B','B'
union select 'C','C'

Diğer listelemede de

Select * from User where username like '@content%'

Buraya kadar herşey normal görünüyor. Fakat bir de bunların en üstünde 'Tüm Kullanıcılar' şeklinde bir durum istenirse nasıl olacak?

Burada sıkıntı olacak 2 durum sözkonusu. Birincisi bu seçeneğin en üstte çıkma gerekliliği, ikincisi ise diğer listeleme sorgusunu kullanarak where koşulunu es geçmek. Eğer like yerine = koşulu olsaydı klasik injection yöntemiyle 'aaa or 1=1' değeriyle çözüme ulaşabilirdik.

Bu durumu ise bir kaç deneme sonucu content değeri için '%' vererek çözebildim. Hem listede en üstte çıktı hemde where koşulunda sınırlama koymadı. Yani (where kolon like '%%') şeklinde where koşulunu işlem dışı yapabiliyoruz.

Belki bir yerlerde işinize yarayabilir.

13 Ağustos 2007

Tablo ve Kolon Listesi

Çok tablolu sistemlerde tablo ve kolon adlarını hatırlamak çoğu zaman zor olmaktadır. Oracle ve SQL Server'da aşağıdaki sorgularla bu bilgilere ulaşabiliriz.

Oracle:

Tablo listesi
select * from tab
select * from tabs
Kolon listesi
select * from col
select * from cols

SQL Server

Tablo listesi
select * from sysobjects where xtype='U',
select * from INFORMATION_SCHEMA.TABLES
Kolon listesi
select * from syscolumns
select * from INFORMATION_SCHEMA.COLUMNS

24 Temmuz 2007

Union All Kullanarak Toplu Insert

UNION komutu kullanarak aynı tipteki değerleri tek transactionda ekleyebiliriz. Örneğin bir kayıt formumuz olsun ve bu formda kişinin okuduğu gazeteleri checkbox tipinde bir kontrolle alalım. Normalizasyonu düşünerek bu değerleri farklı bir tabloda UserId ve GazeteId olarak tutalım. Standart yöntemle bir döngü içerisinde her seçili olan kayıt için bir insert komutu çalıştırılır. Fakat bu döngü içinde seçili olanları UNION ALL ile birleştirip tek sorguda kaydı yapabiliriz.

Sorgumuz aşağıdaki şekilde oluşur;



Kayıt sayısının çok fazla olduğu durumlarda işlem süresindeki kazancımız ciddi oranda artacaktır.

19 Temmuz 2007

Sql Server'dan Oracle'a Geçiş

Yazılım projelerinde veritabanı olarak Oracle ve Sql Server hatırı sayılır bir büyüklüğe sahiptir. Bu nedenle bir çoğumuz iki veritabanıyla da uğraşmak durumunda kalabiliriz. Sql Server'da iyi derecede olup Oracle'a geçişi kolaylaştırmak için başlangıç düzeyindeki farkları yazmanın faydalı olacağını düşündüm. Verdiğim tüm örneklerde Sql Server ifadelerini büyük harflerle Oracle ifadelerini küçük harflerle yazacağım.

Öncelikle çok kullanılan bir kaç fonksiyona bakalım;
GETDATE() - sysdate
ISNULL - nvl
CONVERT(VARCHAR,x) - to_char(x)
CONVERT(DATETIME,x) - to_date(x)
LEN - length
+ -

SELECT * INTO NEW_TABLE FROM TABLE şeklindeki SELECT INTO kalıbı yerine Oracle'da create table new_table as select * from table ifadesini kullanabiliriz.

İki tarih arasındaki fark için kullandığımız DATE_DIFF in direk karşılığı Oracle'da yok. date_diff_month(date1,date2) fonksiyonuyla ay farkını alabiliriz. Ayrıca date2-date1 ifadesi direk olarak gün cinsinden sonuç vereceği için gün farkı için bunu kullanabiliriz.

Değişken tanımlamada
DECLARE @a
INTEGER SET
@a=3
şeklindeki ifade Oracle'da
declare a number;begin a := 3;end;

Sql Server'da bir objeden bağımsız olarak SELECT 1 şeklinde bir sorgulama yapabiliriz. Oracle'da ise dummy table olarak adlandırılan DUAL tablosundan sorgulama yapmamız gerekecektir.
select 1 from dual