Part 3 Bilgi : cursor ve lock LockTypeEnum: 1) adLockBatchOptimistic (değer: 4) : batch update modunu kullanmak istiyorsanız lock u bu şekilde tanımlamanız gerekiyor. 2) adLockOptimistic (değer: 3) : update kullanıldığında kullanılır 3) adLockPessimistic (değer: 2) : değiştirilen veriler veritabanına mümkün olan en kısa sürede ekleniyor 4) adLockReadOnly (değer: 1) : veritabanında değişiklik yapılamaz, sadece görüntülenebilir 5) adLockUnspecified (değer: -1) : lock tanımlanmıyor CursorTypeEnum: 1) adOpenDynamic (değer: 2): RecordSet üzerinde yapılabilecek tüm hareketler yapılabiliyor (Move , MoveNext , gibi). Başka programlar tarafından sizinle aynı anda yapılmış değişiklikler görüntülenebiliyor. 2) adOpenForwardOnly (değer: 0): Tek yönlü ve sadece ileri hareket edebilirsiniz. . Geriye dönüşe ihtiyacınız yoksa o zaman bu cursoru kullanarak yazılımınıza hız kazandırabilirsiniz. 3) adOpenKeyset (değer: 1) : adOpenDynamic e benzer ama adOpenDynamic deki gibi tam bir paylaşım ortamı yoktur. 4) adOpenStatic (değer: 3): Veritabanının tam bir kopyasını çıkarır. Siz bu cursor la bir recorset açar, baska bir yazılımda sizden sonra açar üzerinde değişiklikler yaparsa o değişiklikleri göremezsiniz. Kaydettiğiniz zaman ise başka yazılımlarca yapılan değişiklikler kaybolur. 5) adOpenUnspecified (değer: -1): cursor tanımlanmıyor Dikkatinizi çekmek istediğim başka bir yerse (2). Burada internette açıklanmayan bir olay gerçekleşiyor. pDb->Execute u kullandığınız zaman pSet iniz otomatik olarak kapanıyor. Burdaki olayın nedeni ise pSet inizin açılışta pDb bağlanmış olması. pDb üzerinde bir değişiklik yaptığınızda pSet in pDb ile olan bağlantısı kopuyor ve sonuç olarak pSet i yeniden açmanız gerekiyor. Şimdi projenizi compile ederseniz çalışması gerekiyor.( üye listesine üye eklemek de aynı şekilde olduğu için orayı atlıyorum RecordSet de gezmek: Veritabanında gezmek için MoveFirst , MoveNext , MovePrevious ve MoveLast metodlarını kullanacağız. Öncelikle IDD_ANA üzerinde iki tane düğme , 5 tane de edit box oluşturunuz ve aşağıdaki kodu //2 ye ekleyiniz: Kod: case IDC_SECKITAP: { if(b 1) //eger pSet acıksa kapat try catch a = 1; b = 1; } break; case IDC_SECUYE: { if(b 1) //eger pSet acıksa kapat try catch a = 2; b = 1; } break; case IDC_ILK: { pSet->MoveFirst ; if(a 1) else if( a 2) else } break; case IDC_GERI: { pSet->MovePrevious ; if( pSet->BeginOfFile -1) if(a 1) else if( a 2) else } break; case IDC_SON: { pSet->MoveLast ; if(a 1) else if( a 2) else } break; case IDC_ILERI: { pSet->MoveNext ; if( pSet->EndOfFile -1) if(a 1) else if( a 2) else } break; RecordSet den verileri RsITEM rs->Fields->Item ->Value makrosu sayesinde aldık. Bu makro sayesinde değişken tipleriyle filan uğraşmamıza gerek kalmadı. Verileri silmek : Veritabanından bazı verileri silmek için « DELETE FROM tablo WHERE SQL komutu kullanılır. Öncelikle IDD_ANA da 1 tane düğme ve 1 tane edit box oluşturunuz ve aşağıdaki kodu //2 ye yerleştiriniz Kod: case IDC_SILKITAP: { if( b 1) pSet->Open("SELECT KITAPNUMARA, KITAPISIM, KITAPDURUM FROM KITAPLIK", vtMissing, adOpenDynamic, adLockBatchOptimistic, -1); len = GetWindowTextLength(GetDlgItem ; if(len 0) else if(len > 0) { if( MessageBox(hwnd, "Kitabı silmek istediğinizden emin misiniz?","ADO WIN32 API", MB_YESNO| MB_ICONEXCLAMATION) IDYES) { len = GetWindowTextLength(GetDlgItem ; if(len > 0) sqlkomut. erase ; sqlkomut. append("DELETE FROM KITAPLIK WHERE ; sqlkomut. append ; sqlkomut. append ; sqlkomut. append "); try catch sqlkomut. erase ; MessageBox(hwnd,"Görev tamamlandı.","ADO WIN32 API", MB_OK|MB_ICONINFORMATION); b = 0; } } } break; Yukarıda silme işlemini yaparken kitap numarasının gerçekte olup olmadığına bakmadık ama gerekli kod zaten daha yukarıda kitap ekleme işleminde var.

part 2 Veritabanına veri ekleme Şimdide veritabanına yazılımımız aracılığıyla nasıl kitap ekleriz onu öğrenelim. Öncelikle IDD_ANA diyalogunda 2 tane edit box oluşturun isimleri IDC_KITAPISIM , IDC_KITAPNUMARA olsun. Ayrıca bir tanede düğme koyalım onun ismide IDC_KITAPEKLE olsun. Aşağıdaki kodu //2 ya eklemeniz gerekiyor: Kod: case IDC_KITAPEKLE: { //kitap numarası kontrol len = GetWindowTextLength(GetDlgItem ; if(len 0) else if(len > 0) { //tamam. kitap numarası var kitapnumara = GlobalAlloc(GPTR, len + 1); GetDlgItemText(hwnd, IDC_KITAPNUMARA, kitapnumara, len + 1); //acaba bu kitap numarası veritabanında varmı? //ogrenmek için filtreleyelim //isimize yarayan tabloyu recordset e koyalım try catch //filtrelem sonucu recordset sonda mı yoksa başka yerdemi if( pSet->EndOfFile!= -1) { //sonda değil demekki numara zaten var o zaman yeniden eklemeyelim //ama kullanıcıya guncellemek isteyip istemedigini soralım if( MessageBox(hwnd,"Bu kitap numarası veritabanında zaten var.\nGuncellemek ister misiniz?","ADO WIN32 API", MB_YESNO|MB_ICONINFORMATION) IDYES) { //evet istedi- ozaman kitap ismini kontrol et len = GetWindowTextLength(GetDlgItem ; if(len 0) else if(len > 0) { //kitap ismini al kitapisim = GlobalAlloc(GPTR, len + 1); GetDlgItemText(hwnd, IDC_KITAPISIM, kitapisim, len + 1); //kitabı guncelle try catch MessageBox(hwnd,"Görev tamamlandı.","ADO WIN32 API", MB_OK|MB_ICONINFORMATION); } } else break; } else if( pSet->EndOfFile -1) { //recordset sonda o zaman kitabı ekle - kitap isim kontrol len = GetWindowTextLength(GetDlgItem ; if(len 0) else if(len > 0) { kitapisim = GlobalAlloc(GPTR, len + 1); GetDlgItemText(hwnd, IDC_KITAPISIM, kitapisim, len + 1); //kitap ismi alındı simdi veritabnına ekle try catch MessageBox(hwnd,"Görev tamamlandı.","ADO WIN32 API", MB_OK|MB_ICONINFORMATION); } } } } break; Açıklama gerekebilecek yerlerde zaten açıklamalarda bulundum ama burda birkaç şeye dikkatinizi çekmek istiyorum. Güncelleme işlemi UPDATE tablo SET yenideğer (WHERE... SQL komutuyla yapıldı. (1) de veritabanının kullanmak istediğimiz tablosunu ve kolanlarını pSet içine pSet->Open la koyduk. İlk parametreyle KITAPLIK tablosundan KITAPISIM KITAPNO KITAPDURUM kolonlarını seçtik. Seçim SELECT kolon FROM tablo SQL komutuyla yapıldı. 3 ve 4 uncu parametrelerle ise kullanmak istediğimiz lock tipini ve cursor tipini seçtik. Aşağıda lock ve cursor tipleri hakkında MSDN den aldığım bazı bilgiler: -

ADO ve Win32 api kullanarak veritabanı yazılımları yapma Giriş Bu yazımda size ADO teknolojisini kullanarak veritabanı yazılımları yapmayı öğretmeye çalışacağım. Veritabanı yazılımımızı yapmak içinse win32 yi kullanacağız yani MFC kullanmayacağız. Burada belirtmem gereken şey ise win32 ile veritabanı yapmak MFC ile veritabanı yapmaktan en az on kat daha zor. Ama veritabanınız win32 api ile daha hızlı çalışacaktır ve en önemlisi ise win32 nin tüm gücünü elinizde bulundurmuş olacaksınız . Bu yazıyı yazma nedenim ise ilk veritabanı yazılımımı (ADO ve win32 api ile) yazarken karşılaştığım sorunlar. Mesela bazı tuzaklar var ve bu tuzaklar hakkında internette herhangi bir doküman bulamadım. ADO dünyasına giriş Veritabanı yazılımımızı yapmaya başlayabiliriz. Mesela çok basit bir kütüphane yazılımı yapalım. Kullanıcı yeni kitap ve üye ekleyebilsin, girişleri görebilsin, değişiklikler yapabilsin ve gerekirse girişleride silebilsin. Ayrıca bide anahtar kelimeye göre veritabanında kitap arama özelliğide koyalım. Başlangıç Proje: Projenizi kutup olarak adlandırın ( Win32 Yazılımı seçmeyi unutmayın ) ve ana. cpp adlı bir dosya oluşturup projenize ekleyin. Ayrıca bir resource dosyası oluşturup onuda projenize ekleyiniz. Resource dosyanızda IDD_ANA adlı bir diyalog oluşturmanız gerekiyor. Veritabanı: Access ile kutup. mdb adlı bir veritabanı dosyası oluşturunuz ve onu C:\ ye koyunuz. kutup. mdb veritabanı dosyasının içinde ise iki tane tablo oluşturunuz. Birincisi KITAPLIK ve bu tablo içerisinde KITAPNUMARA KITAPISIM KITAPDURUM adlı 3 tane kolon oluşturunuz. İkinci tabloyu ise UYELISTE olarak adlandırınız ve UYENUMARA UYEISIM adlı iki tane kolon oluşturunuz. Tüm kolonların veri tipi olarak yazı seçmeyi unutmayınız. Ayrıca veritabanına kafanıza göre birkaç kitap ve üye eklersiniz yazılımın yapımı sırasında denemelerde kullanabilirsiniz. ana. cpp dosyasının içine şu kodları ekleyiniz: (comctl32. lib dosyasını linklemeyi unutmayınız...) Kod: #include <windows. h> #include <icrsint. h> #include <iostream. h> #include <string> #include <sstream> #include <commctrl. h> #include "resource. h" //std için using std::string; //Aşağıdaki import olmadan win32 api ile ADO yazılımları yapamazsınız. //Burada yapılan şey ado dll sinin yazılımınıza eklenmesi //burada ado dll sinin kendi bilgisayarımdaki adresini yazdım. //Büyükbir ihtimalle sizinki başka bir yerdedir. Bilgisayarınızda bir arama //yapıp tam adresi buraya yazmanız gerekiyor. //Ayrıca EOF ve BOF uda uyumluluk sorunları çıkmasın diye //isimlerini değiştirmemiz gerekiyor "BeginOfFile" ve "EndOfFile" diye //değiştiriyoruz #import "c:\Program Files\Fichiers Communs\System\ADO\msado15. dll" \ no_namespace rename no_namespace rename #define CREATEiNSTANCE //////////////////////////////////////////////////////// //ado ile kullanacağımız değişkenler _RecordsetPtr pSet = NULL; //recordset için _ConnectionPtr pDb = NULL; //veritabanı için _variant_t vRecsAffected(0L); //0 değerli bir değişken //////////////////////////////////////////////////////// /////////////////////////////////////// //ole yi açma ve kapamada kullanacağız struct InitOle { InitOle InitOle } _init_InitOle_; /////////////////////////////////////// //Aşağıdaki kod ise MSDN de bulduğum bir örnekte kullanıla veritabanından //veri almaya yarayan bir makro. İşinizi gerçekten kolaylaştıracak. #define RsITEM rs->Fields->Item ->Value #define UC //////////////////////////////////////////////// //yazılımda kullanılacak değişkenler //////////////////////////////////////////////// int len = 0; //edit box lar için string sqlkomut; //SQL komutarı için değişken string filtre; //Filtreler için değişken int a = 0; //tablolar arası geçiş için gerekli değişken int b = 0; //pDB kullanımını haber veren değişken char kitapnumara = new char ; char kitapisim = new char ; char uyenumara = new char ; char uyeisim = new char ; ///////////////////////////////////////////////// Evet gereken tüm değişken ve dll leri tanımladık. Ayrıca SQL komutları için std değişkenleri kullanacağız. Şimdi ise gereken dlgproc lari ve winmain i tanımlayacağız. Burada ilerde bulmamız kolay olsun diye base yerlere //1 gibi yazılar koyacağım... İleride eklememiz gereken kodlar olursa oralara ekleyeceğiz Kod: //ana pencere için kullanılan proc BOOL CALLBACK DlgProcAna { switch { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(LOWORD { //2 case IDOK: break; case IDCANCEL: break; } break; default: return FALSE; } return TRUE; } int WINAPI WinMain //makroyu undefine yapıyoruz #undef UC Veritabanına bağlanıyoruz! DlgProcAna da WM_INITDIALOG u doldurmamız gerekiyor (//1): Kod: try { CREATEiNSTANCE ; //(1) pDb->ConnectionString = L"driver= ;SERVER= ;Database=pubs;" L"UID=sa; PWD=;"; //(2) pDb->ConnectionString = L"DRIVER= ; DBQ=kutup. mdb;DefaultDir=C:\\"; //(3) pDb->Open( "", "", "", -1 ); CREATEiNSTANCE //(4) pSet->PutRefActiveConnection ; } catch try ve catch leri kullanmak zorunda değilsiniz ama oluşabilecek hatalar hakkında ayrıntılı bilgi istiyorsanız kullanmanızı tavsiye ederim. (1) de veritabanına bağlanmamıza yarayan connectionstring i doldurduk. connectionstring de bağlanacağımız veritabanının SQL veritabanı olduğunu belirttik. Yerel veritabanı olduğunu belirttik. Veritabanınız kullanıcı adı ve şifre gerektiriyorsa kullanıcı adını UID e şifrenizi ise PWD ye yazmanız gerekmektedir. (2) de veritabanının tipini ve adresini belirttik. Veritabanımız C: de kutup. mdb adlı Microsoft Access veritabanı. (3) de veritabanını açtık. Dikkat ederseniz herhangi bir ayar yapmadık çünkü ayarları yukarıda connectionstring i tanımlarken yaptık. (4) de RecordSet imizi veritabanına bağladık. Bağlantı için gerekli olan herşeyi tanımladık. -