Herşeyiyle Stored Procedur (Firebird / Interbase)

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Herşeyiyle Stored Procedur (Firebird / Interbase)

Mesaj gönderen Fatih! » 24 May 2005 12:43

Stored Procedure Oluşturma

Kod: Tümünü seç

SET TERM ^ ;


CREATE PROCEDURE SP_BASIT (AD VARCHAR(15) CHARACTER SET WIN1254)
RETURNS (EN_BUYUK_SIRA_NO INTEGER)
AS
begin
select max(SIRA_NO) FROM musteri

WHERE ADI=:AD
into :EN_BUYUK_SIRA_NO;
suspend;
end ^
 

 SET TERM ; ^

 

GRANT SELECT ON MUSTERI TO PROCEDURE SP_BASIT;

 
Yukarıda en basit şekliyle bir procedure görmekteyiz. adım adım daha komplike Stored Procedure öğreneceğiz.

şimdi Stored Procedureyi tanıyalım

CREATE PROCEDURE > bu kodla prosedürü oluştur komutu veriyoruz. hemen sonrasında prosedüe bir isim vermemiz gerekiyor. ben SP_BASIT Diye bir isim seçtim. siz istediğiniz bir ismi seçebilirsiniz.ö isim tanımlamadan sonra input ( Gitriş ) parametresi olarak adlandırdığımız Alan isimlerini tanımlıyoruz.

(AD VARCHAR(15) CHARACTER SET WIN1254) Gördüğünüz gibi önce alan ismi Sonra alan tipi ve uzunluğunu tanımladıktan sonra Char ve Varchar tipleri için Türkçe karakter desteğini gösteriyoruz. Tıpkı tablolardaki alan tanımlaması gibi,

peki input (giriş) parametresi nedir. input parametrelerini bir değişken yada alan gibi düşünebilirsiniz. input parametreleri dışardan bilgi alıp Stored Procedurede kullanmanızı sağlar. örneğin yukarıda Stored Procedure içinde yazdığımız sorgudaki şart İnput parametreinde tanımladığımız Ad parametresine göre sorguyu gerçekleştiriyor.

Kod: Tümünü seç

select max(SIRA_NO) FROM musteri

WHERE ADI=:AD
AD parametresine FAOsoft değerini verdiğinizi düşünürsek Stored Procedureyi çalıştırdığınızda Musteri tablosunda Adı FAOsoft olan kayıtlar arasında musteri tablosundaki Sıra_no alanında en büyük sayıyı tutan kaydın numarasını sonuç olarak döndürüyor. .

Etkisini görmek için Tools menüsünden SQL Editor açıp şu kodu Select * from SP_BASIT ('FAOsoft') yazın Run buttonuna basın. Gördüğünüz gib tıpkı bir tablo gibi sorguluyoruz. burada gönderdiğimiz parametreyi parantez içine alıyoruz. input parametresinden sonra tanımladığımız RETURNS (EN_BUYUK_SIRA_NO INTEGER)
Bu bölümede Output ( çıkış ) parametresi diyoruz çıkış parametreleri Stored Procedurede sorgudan çıkan sonucu Gösterir. OUTPUT parametresi tanımlamazsanız Stored Procedure çalışır ama herhangi bir sonuç döndürmez. Sonuç Döndürmesi için mutlaka Output parametresi tanımlayın . Output parametresi tanımlamadan önce mutlaka RETURNS Komutunu kullanmalısınız. Output parametrelerinide tıpkı input parametreleri gibi tanımlayın. input parametrelwerini Where bölümünde kullandığım alanlarla beraber kullanıyorduk. Output parametreleri ise SP ( stored procedurelere kısaca SP dicem) lerde kullandığımız Sorgu cümlesinde Select ve from arassında seçtiğimiz alanlarla koordineli bir şekilde çalışır.

select max(SIRA_NO) FROM buradan çıkan sonuç OUTPUT parametresi tanımladığımız EN_BUYUK_SIRA_NO parametresine atanır. atama işlemi where bölümündeki şarttan sonra yazdığımız into komutu ile gerçekleşir into komutundan sonra Output parametreinnde tanımladığımız parametreleri önüne ( : ) ekleyerek tanımlayın.

örnek

Kod: Tümünü seç

into :EN_BUYUK_SIRA_NO;


AS > INPUT ve OUTPUT parametreleri ile SP'yi birbirinden ayırt edebillmeyi kolaylaştırır.



suspend; > bu komutu Output parametresi tanımladığınızda End'den önce kullanmalısınız. Output parametresi tanımlayıp Suspend'i kullanmazsanız SP çalışacak ancak herhangi bir değer geriye döndürmeyecektir.



SP'nin başındaki SET TERM ^ ; ve Stored Procedurenin sonundaki SET TERM ; ^ tanmlamaları SP'nin aktif databaseye ait olduğunu gösterir. End'in sonundaki ^ işareti ise sp nin bittiğini göterir. Buradaki ( ^ ) işareti yerine istediğiniz karakteri kullanabilirsiniz. Varsayyılanı değiştiremenizi tavsiye ederim. Sayfadayer işgal etmemesi için aşağıdaki örneklerde kullanılmamıştır.

Sorgu Begin ve End Bloğu Arasında olmalıdır. sorgu sonunda ( ; ) kullanılmalıdır.

son olarak GRANT fonksiyonuyla musteri tablosundan seçme hakkını alıyoruz.

seçme hakkını kaldırmak için GRANT yerine REVOKE fonksiyonunu kullanınız. bu komutun kullanımı ilerki konularda anlatılmıştır.

Kod: Tümünü seç

GRANT SELECT ON MUSTERI TO PROCEDURE SP_BASIT;

REVOKE  SELECT ON MUSTERI TO PROCEDURE SP_BASIT;
select yerine SP'nin yapacağı işlem yada işlemleri yazmalısınız.



1. all : Select, delete, insert, update, execute haklarını içerir.
2. select : Bir tablonun tümünü veya bir kısmını görüntüleyebilme.
3. delete : Bir tablodan veya görüntüsünden (view) kayıt silebilme.
4. insert : Bir tabloya veya görüntüsüne kayıt ekleyebilme.
5. update : Bir tablodaki veya gürüntüsündeki kayıtları güncelleyebilme.
6. execute : Bir Depolanmış yordamı (Stored Procedure) çalıştırabilme.


Örnek 2


Kod: Tümünü seç

CREATE PROCEDURE SP_BASIT2 (SIRA INTEGER)
RETURNS (AD VARCHAR(15) CHARACTER SET WIN1254, SOYAD VARCHAR(15) CHARACTER SET WIN1254)
AS
begin
select SIRA_NO, ADI, SOYADI FROM MUSTERI
where musteri.sira_no=:SIRA
into :SIRA, :AD, :SOYAD;
suspend;
end


yukarıdaki örnekte 3 Output parametresi tanımladık 1'den fazla parametrede aralarına ( , ) konur. tanımlanan input ve Output parametreleri ve sorguda kullanılan alan adları aynı özelliklere (alan tipi,alan uzunluğu vb.) sahip olmalıdır.



Örnek 3



Şimdiye kadar yaptığımız SPler Tek kayıt yada tek değer dönderiyordu. SP'den birden çok kayıt alabilmek için sorgumuzu FOR..DO Bloğu içine yazıyoruz.

Birden çok kayıt döndüren SPlerde Delphi içinden IBQUERY veya IBDATASET gbi bileşenlerinden birini kullanın . IBSTOREDPROC bileşenini kullanırsanız hata alırsınız.

Kod: Tümünü seç

CREATE PROCEDURE SP_tumunu_Listele 
RETURNS (AD VARCHAR(15) CHARACTER SET WIN1254, SOYAD VARCHAR(15) CHARACTER SET WIN1254)
AS
begin

FOR
select SIRA_NO, ADI, SOYADI FROM MUSTERI
into :SIRA, :AD, :SOYAD;

DO

begin
suspend;

end

end


For...Do kullanıldığında SP'de başka komut varsa başka bir Begin End bloğu arasına alınır.

Örnek 4

Aşağıdaki SP adı FAOsoft Olan tüm kayıtları listeler.


Kod: Tümünü seç

CREATE PROCEDURE SP_tumunu_Listele2 (ADIM VARCHAR(15) CHARACTER SET WIN1254)
RETURNS (AD VARCHAR(15) CHARACTER SET WIN1254, SOYAD VARCHAR(15) CHARACTER SET WIN1254)
AS
begin

FOR
select SIRA_NO, ADI, SOYADI FROM MUSTERI

where musteri.ADI,=:ADIM
into :SIRA, :AD, :SOYAD;

DO
suspend;
end



SP İle Kayıt Silme
Aşağıdaki SP de input parametresine verilen numaraya eşit olan kayıtlar silinir.

Kod: Tümünü seç

CREATE PROCEDURE SP_SIL (SIRA INTEGER)
AS
begin
DELETE FROM musteri WHERE musteri.sira_no=:SIRA;
end
Yukarıda gördüğümüz gibi Output parametresi olmadığı için Suspend komutunu kullanmadık.

SPde silme işlemi ve dolaylı olarak seçme işlemi gerçekleştiği için Grant bölümü aşağıdaki şekilde olmalıdır.


Kod: Tümünü seç

GRANT SELECT,DELETE ON MUSTERI TO PROCEDURE SP_SIL;


SP İle Kayıt Ekleme


Kod: Tümünü seç

CREATE PROCEDURE SP_EKLE (SIRA INTEGER, AD VARCHAR(15) CHARACTER SET WIN1254, 

SOYAD VARCHAR(15) CHARACTER SET WIN1254)
AS
begin
INSERT INTO musteri (SIRA_NO,ADI,SOYADI)
VALUES (:SIRA, :AD, :SOYAD);
end


Yukarıda kullandığımız gibi bildiğimiz SQL koduyla parametrelerin başına ( : ) işaretini ekleyerek parametrelere gönderilen bilgileri tabloya ekliuyoruz.



Grant bölümü aşağıdaki şekilde olmalıdır.

Kod: Tümünü seç

GRANT INSERT ON MUSTERI TO PROCEDURE SP_EKLE;


SP İle Kayıt Güncelleme

Kod: Tümünü seç

 

CREATE PROCEDURE SP_GUNCELLE (
SIRA INTEGER,
AD VARCHAR(15) CHARACTER SET WIN1254,
SOYAD VARCHAR(15) CHARACTER SET WIN1254,
YENI_SIRA INTEGER)
AS
begin
update musteri
set SIRA_NO=:YENI_SIRA, ADI=:AD, SOYADI=:SOYAD
where SIRA_NO=:SIRA;
end


Yukarıdaki kodda değiştirilmek istenen kaydın primary key değerini Sıra parametresine verip diğer parametrelerede yeni değerleri aynı mantıkla SQL Kodlarıyla atıyoruz.



Grant bölümü aşağıdaki şekilde olmalıdır.

Kod: Tümünü seç

GRANT SELECT,UPDATE ON MUSTERI TO PROCEDURE SP_GUNCELLE;


SP'de Değişken Kullanma



SP'de değişken tanımlama AS Begin sözcükleri arasında yapılır. Değişkenler Declare Variable ile belirtilir. Her değişken tanımından önce Declare Variable tanımı kullanılmalıdır. her değişkenm tanımında nokktalı virgül bulunmalıdır.

Değişken, input,Output parametrelerinin tipleri ve özellikleri tablolarda kullandığımız alan tiplerini ve özelliklerini kullanırlar. IB / FB'de End sözcüğünden sonra noktalı virgül kullanılmaz.

/*bu iki işaret arasında yazılanlar açıklamadır. IB / FB bu yazıları dikkate almaz*/

Kod: Tümünü seç

CREATE PROCEDURE SP_VAR_ORNEK (SIRA INTEGER)
AS
DECLARE VARIABLE NUMARACONTROL INTEGER;
DECLARE VARIABLE ADCONTROL VARCHAR(15) CHARACTER SET WIN1254;
begin
select SIRA_NO, ADI FROM MUSTERI
where musteri.sira_no=:SIRA
into :NUMARACONTROL, :ADCONTROL; /* sorgu soonucu  input ,output  gibi değişkenlere atanıyor*/
if ((NUMARACONTROL=1) and (ADCONTROL='FAOsoft')) then  /* seçilen kaydın nosu 1 adı FAOsoftsa*/

Begin
exception silmemezsin;  /* daha önce tanımladığımız mesajı göster*/

Exit ; /* SP DEN ÇIKIŞ. kullandığımız  exit komutu burada gereksizdir amaç Öğrenmek*/

end
else  /* seçilen kaydın nosu 1 adı FAOsoft değşilse sil*/
DELETE FROM musteri WHERE musteri.sira_no=:SIRA;
suspend;
end


Grant bölümü aşağıdaki şekilde olmalıdır.

Kod: Tümünü seç

GRANT SELECT,DELETE ON MUSTERI TO PROCEDURE SP_VAR_ORNEK;


if then else Kullanımı



Delphide kullandığımızın benzeridir.

Elseden önceki komutada Noktalı virgül konur. then veya elsedeki komut birden fazlaysa delpbideki gibi Begin ve End bloğu arasına yazılır. if...then arasındaki şart parantez içine alınır. if..then arasında birden fazla şart varsa şartların hepsi bir parantez içine eklenir(kendi parantezleri ile birlikte). yukarıda örneklendirilmiştir.



Tablo Kullanmayan SP


SPler her zaman tablolardaki işlemleri yapmak için kuıllanmayabiliriz.

Aşağıdaki örnek SP verdiğiniz tarihin haftanın hangi güne denk geldiğini bulacaktır.

Kod: Tümünü seç


CREATE PROCEDURE SP_GUN_BUL (
TARIH DATE)
RETURNS (
GUN_ADI VARCHAR(10))
AS
DECLARE VARIABLE BENIM_TARIH DATE;
DECLARE VARIABLE TARIH_KOPYASI DATE;
DECLARE VARIABLE FARK1 INTEGER;
DECLARE VARIABLE FARK2 INTEGER;
DECLARE VARIABLE GUN_FARKI INTEGER;
DECLARE VARIABLE SONUC INTEGER;
begin
/*DEGİŞKENLERE ATAMA YAP*/
BENIM_TARIH= '15.12.96'; /*HERHANGİ BİR PAZAR GUNU*/
TARIH_KOPYASI= :TARIH;
FARK1 = 1;
FARK2 = 2;
/*HESAPLA*/
WHILE (:FARK1 <> :FARK2) DO
BEGIN
FARK1 = TARIH - BENIM_TARIH;
GUN_FARKI = :FARK1 / 7;
FARK2 = :GUN_FARKI * 7;
IF (:FARK1 <> :FARK2) THEN
TARIH = :TARIH + 1;
END
SONUC = 7-(:TARIH-:TARIH_KOPYASI);
if (SONUC=1) then
GUN_ADI='Pazartesi';
else
if (SONUC=2) then
GUN_ADI='Salı';
else
if (SONUC=3) then
GUN_ADI='Çarşamba';
else
if (SONUC=4) then
GUN_ADI='Perşembe';
else
if (SONUC=5) then
GUN_ADI='Cuma';
else
if (SONUC=6) then
GUN_ADI='Cumartesi';
else
if (SONUC=7) then
GUN_ADI='Pazar';
suspend;
end


Tools> SQL Editörü açıp oraya şu kodu yazarak etkisini görebilirsiniz.

Kod: Tümünü seç

select * from sp_gun_bul ('26.02.2005')


Yukarıda kullandığımız WHILE şart DO Delphide kullandığımızın benzeridir ve verilen şart gerçekleşinceye kadar işler. WHILE şart DO dan sonra yazılan komut sayısı birden fazlaysa Begin ve End bloğu arasında yazılır.

Değişkenlere = ( eşittir) simgesi ile değer atıyoruz. = ( eşittir) simgesi ile ayrıca karşılaştırma içinde kullanılır.



SP veya Trigger İçinden Giriş Parametreli Sp Çağırma


EXECUTE PROCEDURE spadı (giriş Patametre1,giriş Patametre2 ) RETURNING_VALUES çıkış Patametre1, çıkış Patametre2

giriş Patametreli bir sp aşağıdaki gibi çağrılır.

Kod: Tümünü seç

EXECUTE PROCEDURE SP_Listele  (10,'FAOsoft')

 
yukarıda gönderdiğimiz bilgi sabittir. (10,'FAOsoft') yerine değişken, input,output parametrelerini kullanarak sp yi çağıralım.



çağıracağımız sp gösterdiimiz kaydı değiştirip yeni halini listelesin


Kod: Tümünü seç

CREATE PROCEDURE SP_GUNCELLE (
SIRA INTEGER,
AD VARCHAR(15),
SOYAD VARCHAR(15))
RETURNS (
SIRAM INTEGER,
ADIM VARCHAR(15),
SOYADIM VARCHAR(15))
AS
begin
update musteri
set SIRA_NO=:SIRA, ADI=:AD, SOYADI=:SOYAD
where SIRA_NO=:SIRA;

select SIRA_NO, ADI, SOYADI FROM MUSTERI
where musteri.sira_no=:SIRA
into :SIRAM, :ADIM, :SOYADIM;
suspend;
end


yukarıdaki sp yi çağıracak sp mizde aşağıdaki gibi olsun

Kod: Tümünü seç

CREATE PROCEDURE SP_CAGIR (
SIRA INTEGER,
AD VARCHAR(15) CHARACTER SET WIN1254,
SOYAD VARCHAR(15) CHARACTER SET WIN1254)
RETURNS (
SIRAM INTEGER,
ADIM VARCHAR(15) CHARACTER SET WIN1254,
SOYADIM VARCHAR(15) CHARACTER SET WIN1254)
AS
begin
execute procedure sp_guncelle :SIRA, :AD, :SOYAD returning_values :SIRAM, :ADIM, :SOYADIM;
suspend;
end


Tools> SQL Editörü açıp oraya şu kodu yazarak etkisini görebilirsiniz.

Kod: Tümünü seç


select * from SP_CAGIR (2,'fao','soft');
2. sp nin

Grant bölümü aşağıdaki şekilde olmalıdır.

Kod: Tümünü seç

GRANT EXECUTE ON PROCEDURE SP_GUNCELLE TO PROCEDURE SP_CAGIR;


CASE...WHEN...THEN...ELSE
Bir değere göre daha fazla alternatifi yerine getirmeyi sağlar.

Kullanım biçimi:

CASE değer

WHEN değer THEN işlem

WHEN değer THEN işlem

ELSE işlem

END



AŞAĞIDAKİ ÖRNEK SELECT İÇİNDE ŞARTLI SORGULAMA YAPIYOR.

select ADI, SOYADI, case when YASI > 50 then 'Yaşlı' else 'Genç' end from DEFTER



haftanın gununu yazan bir ornek :

Kod: Tümünü seç

select case extract(weekday from :TARIH) 
             when 0 then 'PZR' 
             when 1 then 'PTS' 
             when 2 then 'SAL' 
             when 3 then 'ÇRŞ' 
             when 4 then 'PRŞ' 
             when 5 then 'CUM' 
             when 6 then 'CTS' 
          end from rdb$database


Örnek

WHEN...DO

When .. Do arasına yazdığınız hata kodu gerçekleşirse Do dan sonra istedğiniz Kodllar yazılarak hata verilmesi engellenir.

WHEN hata1, hata2,hata3 ANY

DO komutlar



ANY birden fazla hata kodundan herhangi birinin oluşması durumunda do'dan sonraki komutların çalışmassını sağlar. tek hata belirtilmişse kullanılmaz. herhangi bir hata belirtilmeyip sadece any i kullanırsanız herhangi bir hata oluşursa yazdığınız kod işler.

do'dan sonra komut sayısı birden fazlaysa Begin ve End bloğu arasında yazılır. .

When .. Do arasına kendi hata şartınızı, exceptionsu, interbasenin ürettiği hataları ve sql kodlarının ürettiği hataları yakalayabilirsiniz.

When .. Do arasına aşağıdaki gbib yazın



sizin şaartınız

SQLCODE SQLkodnumarası ............ sql kodlarının ürettiği hataları

GDSCODE hatakodu ............... interbasenin ürettiği hatalar



Önek

Kod: Tümünü seç

CREATE PROCEDURE NUMBERPROC (A INTEGER) RETURNS (B INTEGER) AS

BEGIN

B = 0;

BEGIN

UPDATE R SET F1 = F1 + :A;

UPDATE R SET F2 = F2 * F2;

UPDATE R SET F1 = F1 + :A;

WHEN SQLCODE -803 DO

B = 1;

END

EXIT;

END!!



Stored Procedure Düzeltme

Tek yapmanız Gereken CREATE PROCEDURE Yerine ALTER PROCEDURE Yazdıktan sonra SP ismini yazıp istediğiniz yerleri değiştirmek.

örneğin SP_GUN_BUL SP sinin sonuc değişkeninin tipini smallint yapalım


Kod: Tümünü seç

ALTER PROCEDURE SP_GUN_BUL (
TARIH DATE)
RETURNS (
GUN_ADI VARCHAR(10))
AS
DECLARE VARIABLE BENIM_TARIH DATE;
DECLARE VARIABLE TARIH_KOPYASI DATE;
DECLARE VARIABLE FARK1 INTEGER;
DECLARE VARIABLE FARK2 INTEGER;
DECLARE VARIABLE GUN_FARKI INTEGER;
DECLARE VARIABLE SONUC SMALLINT;
begin
/*DEGİŞKENLERE ATAMA YAP*/
BENIM_TARIH= '15.12.96'; /*HERHANGİ BİR PAZAR GUNU*/
TARIH_KOPYASI= :TARIH;
FARK1 = 1;
FARK2 = 2;
/*HESAPLA*/
WHILE (:FARK1 <> :FARK2) DO
BEGIN
FARK1 = TARIH - BENIM_TARIH;
GUN_FARKI = :FARK1 / 7;
FARK2 = :GUN_FARKI * 7;
IF (:FARK1 <> :FARK2) THEN
TARIH = :TARIH + 1;
END
SONUC = 7-(:TARIH-:TARIH_KOPYASI);
if (SONUC=1) then
GUN_ADI='Pazartesi';
else
if (SONUC=2) then
GUN_ADI='Salı';
else
if (SONUC=3) then
GUN_ADI='Çarşamba';
else
if (SONUC=4) then
GUN_ADI='Perşembe';
else
if (SONUC=5) then
GUN_ADI='Cuma';
else
if (SONUC=6) then
GUN_ADI='Cumartesi';
else
if (SONUC=7) then
GUN_ADI='Pazar';
suspend;
end




bu şekilde içindeki kodlarıda değiiştirebilirsiniz.

Stored Procedure Silme

DROP PROCEDURE ADI;



Örnek

Kod: Tümünü seç

DROP PROCEDURE SP_GUN_BUL; 


SP kullanımdaysa veya başka bir SP yada Trigger tarafından kullanılıyorsa silinmeyeceektir



Not : Grant vb. ni IB Expertle kolayca halledebilirsiniz. amaç mantığını bilmeniz. SP ve, Viewler tablolar gibi seçilebildiğinden aynı isme sahip olamaazlar. Bir sp ile tablo silme vb.. yapamazsınız. sp de kullandığımız kodları triggerdada kullanabiliriz.

Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! » 24 May 2005 12:48

IB Expert'le Stored Procedure Oluşturma
Procedures e sağ tıklayıp New Procedure dediğinizde aşağıdaki gibi bir pencere gelecektir

Resim
En son Fatih! tarafından 13 Tem 2005 10:42 tarihinde düzenlendi, toplamda 1 kere düzenlendi.

Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! » 24 May 2005 12:56

IBStoredProc Bileşeni
IBStoredProc Bileşenini Birden fazla kayıt döndürmek için kullanamazsınız. SP'den Birden fazla Kayıt Dönecekse mutlaka ibquery veya ibdataset kullanmalısınız.

Tek sonuç, tek kayıt dönderiyorsa yada sonuç döndürmüyorsa güncelleme, silme gibi ibstoredprocedure bileşeninni kullanabilirsiniz. .

bu bileşenin kullanacağı veritabanındaki sp nin yapacağı işlemler için göndereceğiniz input ( giriş ) parametre değerlerini bileşeni çalıştırmadan önce atamalısınız..

Return ( çıkış) Parametrelerinden dönen değerleri ise bileşeni çalıştırdıktan sonra değişken vb.ne atayabilirsiniz..


ransection,ibdatabase,Datasource ve ibdataset ekleyip bağlantıları yaptığınızı varsayarak bileşenin kullanımını öğrenelim.

Aşağıdaki gibi bir tablomuz olsun
Resim
formunuza ibt
IBStoredProc'u forma veya data module koyduktan sonra object inspectordan Database, Transaction özelliklerini forma eklediğiniz Database, Transaction'ı ayarlayın.

aşağıdaKi GİBİ bir sp yazarak.

Kod: Tümünü seç

CREATE PROCEDURE SP_SIL (
SIL INTEGER)
AS
begin
DELETE FROM musteri
WHERE musteri.sira=:SIL;
end


Formunuza eklediğiniz IBstoredProc bileşeninin StoredProcName özelliğini Oject inspectordan yukarıda yazdığımız stored procedure'ün ismini seçin.

örneğimizde seçili kaydı IBStoredProc bileşeni yardımıyla seçili kaydın silinmesini sağlıyacağız.. bunun için bir buttonun Onclick olayına aağıdaki kodu yazıyoruz..


Kod: Tümünü seç

IBStoredProc1.Prepare;
IBStoredProc1.Params.ParamByName('SIL').Value :=IBQuery1SIRA.Value;
IBStoredProc1.ExecProc;  
IBStoredProc1.Unprepare;


IBStoredProc1.Params.ParamByName('SIL').Value :=IBQuery1SIRA.Value; burada sp nin SIL adlı input parametresine tablouzda aktif olan kaydın Primary Key alanın değerini aktarıp bu nu0maraya sahip kay9dı siliyoruz.

ExecProc komutu ibquery,ibdataset,tablenin Active ve Open komutlarıyla aynıdır. bu komutu vermeden bileşen görevini yapmayacaktır.. kesinlikle ibstoredproc bileşeninde active ve open komutu kullanmayın. bileşeni çalıştırma komutu ExcProc olduğu için input parametrelerini bu komuttan önce veriyoruz. aynı şekilde Output (çıkış) parametrelerini bu komuttan sonra alıyoruz.

Prepare ve Unprepare ifadeleri seçimliktir. İsterseniz yazmayabilirsiniz. Bu ifadeler stored procedure'ü birden çok kez çalıştıracaksanız faydalıdır. Mesela peş peşe 3 işçi silecekseniz Prepare komutunu verin, 3 işçiyi silin, Unprepare komutunu verin. İşlem daha hızlı yapılacaktır.



Şimdide çıkış parametreli bir örnek yapalım. örnek sp miz Firebird bölümünde hazırlamış olduğumuz verilen tarihin haftanın hangi gününe denk geldiğini bulan procedureyle örneğimizi uyguluyoruz.

sp kodu

Kod: Tümünü seç

CREATE PROCEDURE SP_GUN_BUL (
TARIH DATE)
RETURNS (
GUN_ADI VARCHAR(10))
AS
DECLARE VARIABLE BENIM_TARIH DATE;
DECLARE VARIABLE TARIH_KOPYASI DATE;
DECLARE VARIABLE FARK1 INTEGER;
DECLARE VARIABLE FARK2 INTEGER;
DECLARE VARIABLE GUN_FARKI INTEGER;
DECLARE VARIABLE SONUC SMALLINT;
begin
/*DEGİŞKENLERE ATAMA YAP*/
BENIM_TARIH= '15.12.96'; /*HERHANGİ BİR PAZAR GUNU*/
TARIH_KOPYASI= :TARIH;
FARK1 = 1;
FARK2 = 2;
/*HESAPLA*/
WHILE (:FARK1 <> :FARK2) DO
BEGIN
FARK1 = TARIH - BENIM_TARIH;
GUN_FARKI = :FARK1 / 7;
FARK2 = :GUN_FARKI * 7;
IF (:FARK1 <> :FARK2) THEN
TARIH = :TARIH + 1;
END
SONUC = 7-(:TARIH-:TARIH_KOPYASI);
if (SONUC=1) then
GUN_ADI='Pazartesi';
else
if (SONUC=2) then
GUN_ADI='Salı';
else
if (SONUC=3) then
GUN_ADI='Çarşamba';
else
if (SONUC=4) then
GUN_ADI='Perşembe';
else
if (SONUC=5) then
GUN_ADI='Cuma';
else
if (SONUC=6) then
GUN_ADI='Cumartesi';
else
if (SONUC=7) then
GUN_ADI='Pazar';
suspend;
end


formunuza bir IBStoredProc, bir datatimepicker,bir edit ve bir de button ekleyin. IBStoredProc bileşenini yukarıdaki gibi ayarlayın. StoredProcName özelliğini Oject inspectordan yukarıda yazdığımız stored procedure'ün ismini SP_GUN_BUL seçin.

ve buttonun onclick olayıına

Kod: Tümünü seç

IBStoredProc1.Params.ParamByName('TARIH').AsDate :=DateTimePicker1.Date;
IBStoredProc1.ExecProc;
edit1.Text:=IBStoredProc1.Params.ParamByName('GUN_ADI').Valu e;
 
yazın. datatimepickerde tarihi seçip buttona tıkladığınızda günü edit içine yazıyoruz. gördüğünüz ggibi giriş parametremizi ExecProc komutundan önce yazıp bileşeni çalıştırdıktan sonra dönen değeri edit içine atıyoruz..



Şimdi Birden Fazla çıkış paramretreli bir sp çalıştıralım.

sp kodıu:

Kod: Tümünü seç

CREATE PROCEDURE Max_Params (
IDNO INTEGER)
RETURNS (
AD VARCHAR(15) CHARACTER SET WIN1254,
SOYAD VARCHAR(15) CHARACTER SET WIN1254)
AS
begin
select ADI, SOYADI FROM tbl_musteri
where tbl_musteri.sira=:idno
into :AD, :SOYAD;
suspend;
end


Öneğimiz verilen numarayı alıp o numaraya ait kaydın adı ve soyadını editlere yazacak. bunıun için

IBStoredProc'u forma veya data module koyduktan sonra object inspectordan Database, Transaction özelliklerini forma eklediğiniz Database, Transaction'ı ayarlayın. StoredProcName özelliğini Oject inspectordan yukarıda yazdığımız stored procedure'ün ismini Max_Params seçin.

forma 3 edit bir button ekleyin. ilk edite bulmak istediğimiz kaydın nosunu yazıyoruz.buttonun onclick olayıına aşağıda ki kodu yazın.


Kod: Tümünü seç

IBStoredProc1.Params.ParamByName('IDNO').AsInteger :=STRTOINT(Edit1.Text);
IBStoredProc1.ExecProc;
Edit2.Text:=IBStoredProc1.Params.ParamByName('AD').Value;
Edit3.Text:=IBStoredProc1.Params.ParamByName('SOYAD').Value;


Koddaki AsInteger :=STRTOINT(Edit1.Text); yerine Value:=Edit1.Text; yazabilirdik. Value Variant bir tipe sahptir. atamayı yapmadan önce değerlerin birbirine uyması için çeviri işlemi yapar. buda performansımızı düşürür. bunun yerine parametrenin veritipini biz belirtebiliriz. Yukarıdaki iki örneği inceleyin.

Birden fazla çıkış parametresi kullandığımız gibi birden fazla giriş parametreside kullanabiliriz..



Birden Fazla kayıt döndüren br sp'yi çağıralım. bunun için IBStoredProc Bleşeni Değil IBQuery veya IBDataset Kullanmalıyız.. örneğimizde IBQuery kullanıyorum.

sp kodıu:

Kod: Tümünü seç

CREATE PROCEDURE SP_LISTELE 
RETURNS (
IDNO INTEGER,
AD VARCHAR(15) CHARACTER SET WIN1254,
SOYAD VARCHAR(15) CHARACTER SET WIN1254)
AS
begin
for
select SIRA, ADI, SOYADI FROM tbl_musteri
into :IDNO, :AD, :SOYAD
do
suspend;
end


formunuza ibtransection,ibdatabase,Datasource ve ibquery ekleyip bağlantıları yapın. IBQuerynin SQL Özelliğine aşağıdaki kodu yazıp. çalıştırın.

Kod: Tümünü seç

select IDNO, AD, SOYAD from SP_LISTELE;
vaya

Kod: Tümünü seç

select * from SP_LISTELE;
gördüğünüz gibi tıpkı bir tablo gibi kullanıyoruz.



Peki Giriş Parameremiz olsaydı? SP mizi Değiştirelim.

Kod: Tümünü seç

CREATE   PROCEDURE SP_LISTELE (
ISIM VARCHAR(15) CHARACTER SET WIN1254)
RETURNS (
IDNO INTEGER,
AD VARCHAR(15),
SOYAD VARCHAR(15))
AS
begin
for
select SIRA, ADI, SOYADI FROM tbl_musteri
where ADI=:isim
into :IDNO, :AD, :SOYAD
do
suspend;
end


IBQuerynin SQL Özelliğine aşağıdaki kodu yazıp. çalıştırın.

Kod: Tümünü seç

select * from SP_LISTELE ('FAOsoft');
yazarsanız ismi FAOsoft olan kayıtlar listelenir. parametre değerini parantez içine yazıyoruz. parametre tipi string değilse tırnak işareti kullanmıyopruz.birden fazla giriş parametresi varsa aralarına virgül ekliyoruz.

Bizde FAOsoft kaydından bbaşlka bir kayırt aramayacakmıyız. ben edit içindeki bilgiyi aratmak şistiyorum dediğinizi duyar gibiyim :))

Forma ek olarak bir edit birde button ekleyin.

buttonun onclick olayına aşağıaki kodu yazın

Kod: Tümünü seç

IBQuery1.Close;
IBQuery1.SQL.Add('select IDNO, AD, SOYAD from SP_LISTELE ('+#39+EDIT1.Text+#39+');');
IBQuery1.Open;


#39 > tırnak işareti anlamına geliyor. Tırnak işaretleri karışmasın diye ben böyle kullanırım. tırnaklar fazlalaştımı.



IBStoredProc Bileşenini seçtikten sonra Object Inspectordan Params özelliğine tıkladığınız zaman karşınıza gelen parametre listesinden birini seçtikten sonra yine Object Inspectordan Value kısmına SP'nin parametrelerine varsayılan değer atayabkilirsiniz.
En son Fatih! tarafından 13 Tem 2005 10:43 tarihinde düzenlendi, toplamda 1 kere düzenlendi.

Kullanıcı avatarı
vedatkaba
Kıdemli Üye
Mesajlar: 866
Kayıt: 06 Oca 2004 06:50
Konum: DARICA/GEBZE

Mesaj gönderen vedatkaba » 03 Haz 2005 04:16

Kod: Tümünü seç

Örnek 3 



Şimdiye kadar yaptığımız SPler Tek kayıt yada tek değer dönderiyordu. SP'den birden çok kayıt alabilmek için sorgumuzu FOR..DO Bloğu içine yazıyoruz. 

Birden çok kayıt döndüren SPlerde Delphi içinden IBQUERY veya IBDATASET gbi bileşenlerinden birini kullanın . IBSTOREDPROC bileşenini kullanırsanız hata alırsınız. 

Kod: 
CREATE PROCEDURE SP_tumunu_Listele 
RETURNS (AD VARCHAR(15) CHARACTER SET WIN1254, SOYAD VARCHAR(15) CHARACTER SET WIN1254) 
AS 
begin 

FOR 
select SIRA_NO, ADI, SOYADI FROM MUSTERI 
into :SIRA, :AD, :SOYAD; 

DO 

begin 
suspend; 

end 

end 
hocam yukarıdaki kodda bulunan

Kod: Tümünü seç

into :SIRA, :AD, :SOYAD;
cumlesinin sonundaki varken kod çalışmadı ama kaldırınca promlemsiz çalıştı.anlaşılan o orda fazlalık.bilginize..

ama güzel bir makale olmuş şehsen teşekkür ederim.başarılar dilerim.
***********************************
Kamil odur ki; koya dünyada bir eser,
Eseri olmayanın, yerinde yeller eser.

***********************************

Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! » 03 Haz 2005 05:35

yanlış hatırlamıyorsam hepsini deneyip eklemiştim. :oops:
teşekkürler

Kullanıcı avatarı
Ali Erdoğan
Kıdemli Üye
Mesajlar: 1026
Kayıt: 11 Şub 2005 02:12
Konum: İstanbul

Mesaj gönderen Ali Erdoğan » 03 Haz 2005 05:39

Eline sağlık dostum.Bu makaleler konusundaki azmini taktir ediyorum...Devamı dileği ile....

Master43
Üye
Mesajlar: 73
Kayıt: 17 Ara 2004 12:05

Mesaj gönderen Master43 » 24 Tem 2005 03:03

:alkis:

Hocam tebrikler çok hoş olmuş elinize sağlık.

Habide #39 yerine delphide QuotedStr fonksiyonu var oda kullanışlı bir fonksiyon.

heskin35
Üye
Mesajlar: 132
Kayıt: 30 Haz 2004 08:48

Mesaj gönderen heskin35 » 09 Eyl 2005 11:20

Çok Saol FaoSoft hocam. Ellerine sağlık açıklayıcı ve güzel bi döküman olmuş.

doganzorlu
Kıdemli Üye
Mesajlar: 395
Kayıt: 22 Tem 2004 08:15
Konum: İzmir
İletişim:

Mesaj gönderen doganzorlu » 09 Eyl 2005 01:40

Selam,

Çok güzel bir döküman, elinize sağlık. Bir ufak hatırlatma yapmak gereği hissettim;
SP'nin başındaki SET TERM ^ ; ve Stored Procedurenin sonundaki SET TERM ; ^ tanmlamaları SP'nin aktif databaseye ait olduğunu gösterir. End'in sonundaki ^ işareti ise sp nin bittiğini göterir. Buradaki ( ^ ) işareti yerine istediğiniz karakteri kullanabilirsiniz. Varsayyılanı değiştiremenizi tavsiye ederim. Sayfadayer işgal etmemesi için aşağıdaki örneklerde kullanılmamıştır.
Burada ifade edilmeye çalışılan, SET TERM ile komut bitiş karakterini set ediyoruz sanırım. Bu karakter daha çok client ile ilgilidir server bununla ilgilenmez. Client (örn isql), girilmiş olan metni ilk önce SQL cümleleri olarak parçalar. Zira bir defada birden fazla komut girmiş olabilirsiniz. Default olarak bunun için ; karakterini kullanır.

Böyle bir durumda, eğer default SQL ayıracı değiştirilmemişse, FB engine e bilgi aşağıdaki gibi gidecektir;

CREATE PROCEDURE SP_GUNCELLE (
SIRA INTEGER,
AD VARCHAR(15),
SOYAD VARCHAR(15))
RETURNS (
SIRAM INTEGER,
ADIM VARCHAR(15),
SOYADIM VARCHAR(15))
AS
begin
update musteri
set SIRA_NO=:SIRA, ADI=:AD, SOYADI=:SOYAD
where SIRA_NO=:SIRA;
<<
>> ERROR


select SIRA_NO, ADI, SOYADI FROM MUSTERI
where musteri.sira_no=:SIRA
into :SIRAM, :ADIM, :SOYADIM;
<<
>> ERROR

suspend;
<<

Bu durumdan kaçınmak için alternatif bir ayıraç set ederiz, örneğin SET TERM !!. Bu komutla SQL komutlarımızın !! ile ayrıldığını söylüyoruz. (Dikkat, database e değil, SQL cümlemizi alıp ona gönderecek client a söylüyoruz bunu zira parse işlemi orada yapılıyor) Bu durumda;


CREATE PROCEDURE SP_GUNCELLE (
SIRA INTEGER,
AD VARCHAR(15),
SOYAD VARCHAR(15))
RETURNS (
SIRAM INTEGER,
ADIM VARCHAR(15),
SOYADIM VARCHAR(15))
AS
begin
update musteri
set SIRA_NO=:SIRA, ADI=:AD, SOYADI=:SOYAD
where SIRA_NO=:SIRA;
select SIRA_NO, ADI, SOYADI FROM MUSTERI
where musteri.sira_no=:SIRA
into :SIRAM, :ADIM, :SOYADIM;
suspend;
.....
!!
<<
>> CREATED

CREATE PROCEDURE SP_KAYDET (
.....

!!
<<
>> CREATED

CREATE PROCEDURE SP_SIL (
.....
!!
<<
>> CREATED

Seklindeki bir metni client, 3 ayrı komut olarak algılayacaktır zira !! ifadesini bitiş karakteri olarak set etmiştik. Bu karakter set iken kullanacağınız tüm SQL cümleleri bununla bitmelidir. Misal;

commit!!

gibi. Tabi alışıldık ; a dönmek daha konforlu olacağından en sonunda;

SET TERM ;!!

diyerek ayıracı tekrar ; haline getiririz.

-----

Çalışmalarınızın devamını bekliyoruz, kolay gelsin.
Doğan Zorlu, İzmir

------------------------
"Bu Kitap'ı sana yalnız şunun için indirdik: Hakkında ayrılığa düştükleri şeyi onlara iyice açıklayasın ve Kitap, iman eden bir topluluk için kılavuz ve rahmet olsun." (NAHL 64)

Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! » 09 Eyl 2005 03:01

herkese Teşekkürler. özellikle doğan beye.
yazdığım makaleler genellikle yabancı kaynaklardan öğrenerek aktarıyorum. bunun gibi bazı durumlarda deneme yanılma şansım pek olmuyor. öğreten kaynakta es geçtiyse olduğu gibi çevirmeye mecbur kialıyorum.
bilgilendirdiğin için teşkkürler.

Cevapla