BilgiTeknoloji.net    
b i l g i   t e k n o l o j i   y a z ı l ı m

Ana Sayfa

Marjinal XML Access Pratik Uygulamalar Projeler Ekonometri Dilimiz Editörden Çetrefil İletişim
 

HERKES İÇİN SQL


İyi sorgular yapabilmek için iyi hazırlanmış tablolarımızın olması gerekiyor. Dizinler, ilişkiler, geçerli değerler (indexes, relationships, default value) gibi yardımcı özelliklerle veritabanımızın sağlamlığını artırabiliriz.


PERFORMANS, AMA NASIL?

Daha önce karşılaştığım bazı ayrıntıları anlatmakla yetineceğim şimdilik. Sorgu yaparken Access’i yoran şeylerden bir tanesi tablolarda tanımlı DevaultValue (Varsayılan) değeridir. Ekranda bir sürü açılan liste kutusu (combobox) varsa ve herbiri kendi listesini başka bir tablodan araştırarak getiriyorsa formumuzun pek hızlı olmasını beklememeliyiz her zaman.

Örneğin veritabanında, beraber çalıştığımız müşteri şirketler ve bunlara ait personel listesi olsun. Kisiler tablosundaki SirketNo adlı alan Sirketler tablosundaki No alanı ile bağlantılı. Yani biz kişilere ait şirket eşleşmesini şirketin ismi yerine numarasını vererek sağlıyoruz. Liste kutularındaki seçeneklerle gerekli eşleşmeleri ayarlayıp kolayca listeleme yapıyoruz.

Öncelikle bu tür eşleştirmelerde mutlaka dizin (indeks) ve ilişki (relationship) tanımlanmalıdır performans için. Aynı şekilde arama yapılacak alanlarda da dizin oluşturulmalıdır. (Sirketler tablosundaki No alanı.)

Asıl söylemek istediğime gelirsem, özellikle şöyle bir ipucu işimize yarayabilir: Eğer varsayılan değeri (default value) sıfır olarak seçilmiş bir alana ait açılan liste kutusunda başka bir tablodaki kayıtları listeliyorsak ve bağlı arama alanı değeri hiçbir zaman sıfır olmayacaksa (mesela autonumber –otomatik sayı alanları için) boş yere sıfır değeri için arama yaptırıp zaman kaybedeceğiz. Zira açılır liste kutusu kendisinde kayıtlı 0 değerini bağlı tablodan arayacak ama hiçbir zaman otomatik sayı türündeki bir alanda bunu bulamayacaktır. Sıfır olmayacak alanlara bağlı sayısal alanlardaki, geçerli olan sıfır değerini kaldırarak formlarımızdaki kayıt geçişlerini bir nebze de olsa hızlandırabiliriz.

Bu, bir süre önce rasladığım küçük ama çok önemli olduğunu düşündüğüm bir ayrıntıydı. Bu ay aslında sorgulardan ve SQL’den bahsetmek istiyorum.


MAZERETİM VAR, SQL BİLMİYORUM

Access ile SQL bilmemize gerek kalmadan hemen her türlü sorgulama işlemini yapabiliriz. Ama yine de Access kullanmadan SQL kodu yazabilmenin inceliklerini birazcık da olsa öğrenmek gerekiyor.

Geçen haftalarda şirketin diğer departmanlarındaki arkadaşlarla bir saat kadar SQL çalıştık. Hepsi de SELECT, FROM, WHERE, ORDER BY başlıkları ile beraber MAX, MIN, SUM, COUNT, TOP, ASC, DESC komutlarını da anlayarak toplantıdan ayrıldılar. Toplantının sebebi uzak erişimli sunucularımızdaki verilere kendi başlarına sadece SQL kodu yazarak ulaşabilmelerini sağlamaktı. Her grup kendi yetki alanı dahilindeki veritabanlarında istediği SQL kodunu çalıştırarak istediği kayıtları listeleyebilmeliydi. Burada da bu ay sadece SELECT komutu dahilinde, yani kayıt listelemek için çalışalım.

SQL’de onu kullanan sistemin yapısına göre yazımda bazı farklılıklar gösterse de yaygın veritabanı sistemlerinin hemen hepsinde kayıt arama ile birlikte, yeni kayıt ekleme, silme, değiştirme ya da veritabanını yönetme gibi gelişmiş özellikler vardır. Mesela Access dosyasında istediğiniz bir tablonun alanlarını ya da dizinlerini SQL kodu ile değiştirebilir veya yeni bir tablo oluşturup bunun içine istediğiniz kayıtları SQL kullanarak ekleyebilirsiniz.


GENELDE SQL

Access bize sorgularda, formlarda, raporlarda, makrolarda ve modüllerde SQL kullanabileceğimizi söylüyor. Kayıt bulup getiren tipik bir SQL cümlesi şu şekildedir örneğin:

SELECT Ad, Soyadi, Yas, Tarih FROM Kisiler WHERE Ad=”Ahmet” ORDER BY Tarih;

Bu komut (FROM) Kisiler adlı tablodan, (WHERE) Adı “Ahmet” olan kayıtları, (ORDER BY) Tarih alanına göre artan sıralayacak ve (SELECT) Ad, Soyadi, Yas, Tarih alanlarını seçecek şekilde getirecektir.

ORDER BY sıralama yapılacak alanı belirtir. Genelde en sonda kullanılıyor. “ORDER BY Tarih” demekle sonucu Tarih alanına göre artan sıralıyoruz. “ORDER BY Tarih ASC” ile arasında fark yoktur. ASC (Ascending) artan sıralamayı belirtiyor. Yerine DESC (Descending) kullansaydık ters sıralama yapılacaktı. Sadece bununla bitmiyor. Birkaç alana göre de sıralama yapılabiliyor bununla. Mesela “.. ORDER BY Tarih DESC, Soyad ASC, Ad ASC” gibi. Yani Tarih’e göre ters sıraladıktan sonra önce Soyad’a ve ardından Ad’a göre düz sırala.

Aradığımız şeyi bulmak için WHERE komutunu kullanmamız gerekiyor.

.. WHERE ( (Ad=”Ahmet”) AND (Soyad=”Kara”) ) ..

şeklindeki bir kriter Ahmet Kara adlı kişinin kaydını arayacaktır. “WHERE Yas>=20” ile 20 yaş ve üzeri kişilerin kayıtlarını bulabiliriz. Ya da “Yas<>20” ile 20 yaşında olmayanlar bulunabilir. Eğer 20-40 yaş arası istiyorsanız “WHERE Yas BETWEEN 20 AND 40” demeniz yeterli.

İsterseniz içinde geçebilecek karakterlere göre de arama yaptırabilirsiniz.

.. WHERE (Ad Like “Ahm*”)..

“Ahm*”: Ahm ile başlayanlar,

“*Ahm”: Ahm ile bitenler,

“*ahm*”: Herhangi bir yerinde AHM olanlar (başında ve sonunda olanlar da dahil),

“*a?m*”: İçinde A olacak, sonraki bir adet harfin ne olduğu önemli değil ama onun yanında M harfi olmalı.

Bazı durumlarda çift tırnak yerine tek tırnak yazmanız gerekebileceğini hatırlamanız faydalı olacaktır. Bu örnekleri SQL cümlesi içindeki WHERE’in bulunduğu kısma yazarsanız çalışır. Tek başına bu kriterler çalışmaz.

FROM ile bildiğiniz gibi hangi tablodan kayıt alınacağı belirtiliyor. Şimdilik sadece tek tablo ile çalışıyoruz. SELECT ile bu tablo içindeki istediğimiz alanları görüntülüyoruz. “SELECT Ad, Soyad FROM ..” gibi bir cümle sadece Ad ve Soyad alanlarının getirileceğini belirtiyor. Bütün alanların gelmesini istiyorsanız “SELECT * FROM Kisiler ..” yazın, olsun bitsin.

Arama kriteri yoksa WHERE kullanmaya, sıralama yapılmayacaksa da ORDER BY kullanmaya gerek yoktur. Yani tek başına çalışabilecek en küçük SQL cümlesi “SELECT * FROM Kisiler” şeklinde olacaktır. Bu, Kisiler tablosundaki tüm kayıtları ve tüm alanları getirir.


ACCESS’TE SQL

Veritabanı penceresinde Sorgu sayfasında yeni bir Sorgu oluşturalım. Sorguyu açtıktan sonra görüntülenen tablo seçme formundan sorgulamak istediğimiz tabloyu seçelim. (Yeni bir dosyada çalışıyorsanız, tabii ki önce bir tablo oluşturmalısınız.) Karşımıza, adının sonundaki sıfatı fazlasıyla hakeden Sorgu Sihirbazı çıktı.

Ben Kisiler tablosunu seçtim. Şimdi yukarıda öğrendiğimiz SQL kodlarını ilk olarak burada deneyebiliriz. Görünüm menüsünden SQL Görünümü’nü seçin.

Bende “SELECT FROM Kisiler;” görünüyor. Bunu, öğrendiğimiz kurallara uyarak;

SELECT Ad, Soyad
FROM Kisiler
WHERE Ad=”Ahmet”

olarak değiştiriyorum. Görünüm menüsünden Tasarım’a geçtiğimizde bakın nasıl bir görüntü çıkıyor (Query2):

SELECT kısmında * işareti de kullanabilirdik. Şöyle bir ayrıntıyı hatırlatmalıyım burada ki, bazı durumlarda tasarım görünümünde bütün alanlar olmamasına rağmen sorguyu çalıştırınca bütün alanlar listelenebiliyor. Bu, sorguların bütün alanları gösterme özelliğinin aktif olmasından dolayıdır. Görünüm menüsündeki Özellikler komutundan çıkan pencerede “Tüm Alanları Göster” (Output All Fields) kısmındaki değeri NO yaparsanız sadece sizin seçtiğiniz alanlar listelenecektir.

Üçüncü örneğimizde (Query3 resmi) Ad, Soyad, No, soyad, Ad alanları seçilmiş.

SELECT Ad, Soyad, [No]
FROM Kisiler
WHERE ( ([No])<100) AND (Soyad) Like "A*") )
ORDER BY Soyad DESC, Ad;

1. No alanının parantez içine alınmasının sebebi “NO”nun özel bir kelime olup yorumlayıcı tarafından “Hayır“ anlamında anlaşılmamasıdır.

2. En sağdaki Soyad ve Ad alanlarının ikinci kez kullanılmasının amacı sıralamayı sütunların sıralanmasından farklı yapabilmek. Yani önce Ad’a sonra Soyad’ göre sıralamak isteseydik baştaki Ad ve Soyad alanlarında sıralama seçerdik. Ama biz önce Soyad’ı istediğimiz için son tarafa bunları koyup Göster (Show) işaretini kaldırdık. (Aynı şeyi 2. soyad alanını birincinin olduğu yere taşıyarak da yapabilirdik. Zira, hem ORDER BY hem de SELECT için seçili alanların sırası aynı olacak.)

3. Sadece Göster (Show) değeri işaretli olan alanlar görüntülenir. Bunlar SELECT kısmına dahil edilir. (Tüm alanları gösterme özelliği kapalıysa tabii.)

4. Dördüncü sütundaki LIKE cümleciğini No alanının alt satırında kullanmamızın sebebi VEYA sorgusu elde edebilmek. Yani “ NO<100 OR SOYAD LIKE ‘A*’ ” gibi. İkisini aynı satırda kullanırsak VE sorgusu elde ederiz ki bu, cümlemizdeki “OR”un “AND”a dönüşeceği anlamına gelir.

Bu tasarım modunda ne kadar karışık ya da sade yaparsak yapalım Access evirip çevirip kendi bildiği gibi bir SQL kodu üretecektir.

SELECT Kisiler.Ad, Kisiler.Soyad, Kisiler.[No], *
FROM Kisiler
WHERE (((Kisiler.[No])<100)) OR (((Kisiler.Soyad) Like "A*"))
ORDER BY Kisiler.Soyad DESC , Kisiler.Ad;

Beşinci madde olarak da şunu ekleyeyim o zaman: Alan isimlerinin başına tablonun ismi yazılabilir. Bu, birden çok sayıda kullanılan tabloların olduğu sorgularda daha işe yarar olur.


EXCEL’DEKİ GİBİ OTOMATİK SAYI SERİLERİ OLUŞTURMAK

Access’te Excel’deki gibi artan satırlarda otomatik sayı oluştumak ne iyi olurdu diye düşündüğünüz olduysa ilk fırsatta deneyin derim. Kayıtlar arasında aşağı giderek seri olabilecek sayılar girin. (Yani 1, 3, 5, 7 .. gibi.) Oklarla aşağı doğru gittikçe yeni değerleri anlayıp sizin yerinize Access yazacaktır.


KENDİ FORMÜLÜNÜ KENDİN HESAPLA

Kullanıcının kendi formülünü hesaplayabilmesini sağlamak istediğiniz oldu mu hiç? EVAL işlevi bu iş için biçilmiş kaftan. Siz formül metnini veriyorsunuz, o da hesaplıyor:

MsgBox Eval(“6^2 + 4*3 – Log(Exp(10))”)


OTOMATİK SAYI

Bazan bu isim kendi kendine çalışan sayılar varmış gibi çağrışımlar uyandırıyor bende. Otomatik çamaşır makinası gibi. Gelgelelim bazı arkadaşlar bunun marifetlerinden pek muzdaripler. “Otomatik sayı, kayıt numarası neyse onu versin”, “Yeni kayda geçip vazgeçtiğimde numarayı çalıyor, bir daha aynı numarayı kullanamıyoruz”, “Bütün kayıtları sildiğim halde 1’den başlamıyor” gibi yakınmalar oluyor.

Efendim, bu otomatik sayı öyle birşeydir ki görüntü açısından bir anlam taşıması için üretilmemiştir. Diğer bütün sistemlerde olduğu gibi en büyük amacı belli bir kayda özel bir kod vererek istendiğinde ona kolayca ulaşabilmeyi sağlamaktır. Mesela bütün alanların değerleri aynı olan iki kaydı birbirinden ancak Otomatik Sayı değerleri ile ayırabilirsiniz. Yani arkaplan işlemleri için kullanılır. Ama isterseniz ekranda da değerini gösterin.

Bunun artan olacak şekilde değerler almasını ayarlayabileceğiniz gibi rasgele değerler almasını da sağlayabilirsiniz. Tablo tasarım görünümünde NewValues (Yeni Değerler) özelliğini Random (Rasgele) yaparak.

Yine de programı kullanacak kişiler açısından bir daha tekrarlanmayacak bir fiş numrası, kod numarası, etiket numarası gibi bir değer elde edilmiş olur. Access’teki replikasyon işleminde de kullanılabilir AutoNumber alanlar.


ACCESS HİKAYELERİ

FARE MENÜSÜYLE MP3 LİSTESİ

Şimdi bunun Access’le ne ilgisi var? Yok tabii. Ama dolaylı olarak Access’le çalışırken MP3 dinlemek istiyor insan. Hele bu eski makinemde Access’le Winamp’ı aynı anda çalıştırmak istemeyen biri olarak Media Player tercihim. Media Player madem MP3 çalıyor, M3U da çalıyor. Hatta M3U liste dosyasının özel bir biçimde yazılmış olmasına gerek yok. Yeni bir metin dosyasının içine MP3 dosyalarının isimlerini klasör adlarıyla birlikte altalta yazın. Metin dosyasını kapatıp uzantısını M3U yapın ve Media Player’da açın.

Yeni bir metin belgesi daha oluşturup şunları aynı şekilde yazın:

@echo off
dir %1\*.mp3 /on /b /a-d >mp3ler.m3u
echo Liste oluşturuldu... OK...
echo Bu pencereyi kapatabilirsiniz...
echo.

Sonra bunu mp3liste.bat adıyla c:\ içine kaydedin. Şimdi de Windows Gezgini'ni (Explorer) açıp Görünüm/Seçenekler menüsünü çalıştırın ve DosyaTürleri (FileTypes) sayfasına geçin. Listeden Klasör'ü (Folder) seçin. Yeni (New) tuşuna basın. Üstteki yere "MP3 Listele", alttaki yere de "c:\mp3liste.bat %1" yazın ve Tamam (OK) tuşuna basın. Yine Tamam (OK) tuşlarıyla işlemleri onaylayın.

Böylece windows’ta herhangi bir klasörün üzerine geldiğinizde sağ fare menüsündeki MP3 Listele komutunu kullanarak o klasördeki MP3'leri aynı klasörün içinde "mp3ler.m3u" dosyasına kaydedebileceksiniz.

Eğer "dir %1\*.mp3 /on /b /a-d /s >mp3ler.m3u" şeklinde "/s" eklerseniz tüm alt klasörleri arayarak klasör isimlerini de dosyaların başına ekler.

Fakat C: D: gibi bir kök dizinde bunu yapıyorsanız bu kod çalışmaz. Çünkü kök dizinlerde parametre olarak \ işareti gelirken klasör isimlerinde bu ek yoktur. O zaman "dir %1\*.mp3..." yerine "dir %1*.mp3..." yazmalısınız.


Fikret Kızılok ve Fahir Atakoğlu favorim :-)

 

Serkan Şahinoğlu
PC Magazine, Ağustos 2000


http://BilgiTeknoloji.net