SlideShare a Scribd company logo
1 of 40
Download to read offline
STORED PROCEDURE
Transact-SQL ifadelerinin bir arada kullanılmasından oluşturulan yapılara Stored
Procedure adı verilir. Stored Procedure farklı yapılarda bulunur.
 System Stored Procedure(sp_): Bu tür procedure'ler, master veri tabanı içinde tutulur
ve genellikle sistem tabloları hakkında bilgi döndürmek için kullanılır. Genel olarak sp
ifadesi ile başlar. Herhangi bir veri tabanı içinde çalıştırılabilir.
 Local Stored Procedure: Kullanıcı veri tabanları içinde, özel olarak tanımlanan
stored procedure'lerdir.
 Temporary Stored Procedure: Geçici olarak oluşturulan stored procedure'lerdir. İki
ayrı yapısı vardır. Sadece belli bir veri tabanında kullanılanlar ve tüm veri
tabanlarında kullanılanlar. Lokalde kullanılanların ismi # ile başlarken, diğeri ## ile
başlar.
 Remote Stored Procedure: SQL Server'ın eski bir kullanımı olan bu yapı,
dağıtılan(distributed) sorgulamalarda kullanılmaktadır.
 Extended Stored Procedure(xp_): DLL'ler tarafından, SQL Server dışında kullanılan
stored procedure'lerdir. Genellikle xp ifadesi ile başlayan bu tür stored procedure'ler,
bazı system stored procedure'leri tarafından da çağrılarak kullanılabilir.
SQL Server içindeki Stored Procedure diğer programlama dillerine benzer;
* Diğer stored procedure'leri çağırabilir.
* Dışarıdan değer alabilir.
* İçinden çağrılan değer; başarılı veya başarısız olarak dönebilir.
* Birden fazla değeri, dışarıya yollayabilir.
Kısacası, Transact-SQL komutlarını kullanarak yapılan programlama olarak ifade
edebiliriz. Ayrıca uygulama yazılımları tarafından aynı anda kullanılması, veri tabanı yapısını
gizlemesi, güvenlik mekanizmasının gelişmiş olması, performansı arttırması ve network
trafiğini azaltması sayılabilecek diğer avantajlarındandır.
STORED PROCEDURE YAPILANDIRMASI:
Bu kısımda artık işe başlıyoruz ve nasıl Stored Procedure oluşturulacağını,
çalıştırılacağını, değiştirileceğini ve silineceğini detaylı olarak inceleyeceğiz.
STORED PROCEDURE NASIL OLUŞTURULUR?
Stored Procedure, aktif veri tabanı içinde oluşturulur. Sadece geçici stored
procedure'ler tempdb veri tabanı içinde tutulur. Stored procedure oluşturma formatı, view
oluşturma formatına benzer. CREATE PROCEDURE ifadesi ile oluşturulur.
Stored Procedure oluştururken aşağıdaki kurallara ve önerilere dikkat etmek gerekir.
* Stored Procedure içinde; tablo, view, kullanıcı tanımlı fonksiyon ve diğer stored
procedure'ler, aynı zamanda geçici tablolar da kullanılabilir.
* CREATE PROCEDURE tanımlaması, sınırsız sayıda ve tipte Transact-SQL
ifadesi içerebilir. Ancak beraber kullanılamayacak ifadelerde vardır. Bunlar;
CREATE DEFAULT
CREATE PROCEDURE
CREATE RULE
CREATE TRIGGER
CREATE VIEW
* CREATE PROCEDURE ifadesini kullanmak için, aşağıdaki haklara veya gruplara
üye olmak gerekir.
sysadmin
db_owner
db_ddladmin
Veya CREATE PROCEDURE iznine sahip olmalı.
* Bir stored procedure'ün en fazla boyutu 128 MB olabilir. Kullanım biçimi;
CREATE PROC[EDURE] procedure_adı[;sayı]
[{@parametre_adı veri tipi]
[WARNING][=default][OUTPUT]][,n]
[WITH{RECOMPLIE|ENCRYPTION|RECOMPLIE,ENCRYPTION}]
[FOR REPLICATION] AS sqljfadesi[leri]
UYGULAMA:
1) Bu konumuzda, bir önceki konuda oluşturduğumuz müşteriler ve satis tablolarını
kullanacağız. Bu tabloda hiçbir index ve kısıtlama olmadığına emin olduktan sonra,
aşağıdaki kayıtların bulunduğunu kontrol ediniz.
2) SQL Server Query Editör içine aşağıdaki ifadeleri yazalım. Bu kod superman
isimli filmleri listeleyecektir.
Use user
Go
Create proc supermanler
As
Select * from satis
Where filmad=’superman’
go
3) Oluşturduğumuz supermanler isimli stored procedure'ü çalıştırmak için, aşağıdaki
gibi exec komutu kutlanılır.
Use cuneyt
Exec supermanler
4) Bunun sonucunda; sadece film adı superman olan kayıtlar listelenecektir.
Bizim örneğimizde, bu sorgulamaya uyan iki kayıt vardır.
5) Oluşan Stored Procedure'ü görmek için; veri tabanı altında bulunan
ProgrammabilityStored Procedures nesnesini kullanabiliriz.
Ayrıca yazdığımız kodu görmek veya üzerinde değişiklik yapmak için, oluşturduğumuz
stored procedure üzerinde sağ tuşa basarak, Modify seçeneğine tıklamamız yeterlidir.
Yine bu Stored Procedure'ü buradaki Execute Stored Procedure seçeneği ile
çalıştırabiliriz.
1) Modify seçeneğine tıkladığımızda, şekildeki yapı karşımıza gelir. Burada
değişiklik yapabiliriz.
2) Grafiksel olarak Stored Procedure oluşturmak; çok fazla avantaj sağlamaz,
ama yine de basit bir stored procedure'ü grafiksel olarak Object Explorer
içinden oluşturmak istersek, veri tabanı altında bulunan ProgrammabilityV
Stored Procedures nesnesi üzerinde sağ tuşa basarak, New Stored Procedure
seçeneğine tıklarız.
3) Gelen ekran; standart bazı yazılar içerir.
4) Aşağıdaki ifade Kasım 2010 yılı ile bugünkü tarih arasında satılan filmleri gösteren
stored procedure'ü oluşturur.
EXECUTE STORED PROCEDURE:
Daha önce de belirttiğimiz gibi bir stored procedure, exec komutu ile çalıştırılır. Ayrıca
bir INSERT ifadesinin parçası olarak da çalıştırılabilir.
Kullanım sekli:
[EXECUTE]
[@ dönen_durum=]
{procedure_adı[;sayı]}
[[parametre)]{değer|@değişken[OUTPUTJ|[DEFAULT]]
[WITH RECOMPLIE]
INSERT ifadesinin kullanım şekli;
insert into tablo_adı
exec storedprocedure_adı
UYGULAMA
1) Aşağıdaki kodu SQL Query Editör içine yazarak, satis tablosuna iki kayıt
ekleyen stored procedure'ü oluşturalım.
USE user
go
create proc yenisatisekle
as
insert into sati values(105,'Hulk',88,'01/22/2011','01/25/2011')
insert into sati values(106,'Hulk',99,'01/23/2011','01/27/2011')
go
2) Yukarıdaki yazılımı çalıştırdığımızda, sadece yenisatisekle isimli bir stored procedure
oluşturur. Kesinlikle bu kodu çalıştırmak, satis tablosuna bir ilave yapmaz. Ekleme yapması
için oluşan stored procedure aşağıdaki şekilde çalıştırılmalıdır.
3) satis tablosunu açtığımız zaman görüntü, aşağıdaki gibi olacaktır.
4) Şimdi de INSERT ifadesi ile beraber Stored Procedure'ü nasıl' çalıştıracağımızı
inceleyelim
Aşağıdaki şekilde "merkez" isimli yeni bir tablo oluşturalım ve içine hiçbir veri
girmeyelim
5) Şimdi, müşteriler içinde 0532 ile başlayan telefonları seçen "turkcelo" isimli
bir Stored Procedure oluşturalım.
create proc turkcelo as
select * from musteri where mtel like '0532%'
6) turkcelo isimli stored procedure'ü, aşağıdaki gibi yazarak çalıştıralım. Bunun sonucunda,
şekildeki gibi sadece 0532 ile başlayan telefon numaraları listelenecektir
Exec turkcelo
7) Şimdi esas yapmamız gereken işi yapalım, turkcelo stored orocedure'ü, 0532 ile başlayan
telefon numaralarını seçiyor. Biz bu özelliği kullanarak 0532 ile başlayan telefona sahip
kayıtları; yeni oluşturduğumuz merkez isimli tabloya kopyalayacağız ve bunun için stored
procedure'ü aşağıdaki gibi INSERT ifadesi ile çalıştıracağız. Aşağıdaki kodu, SQL Server
Query Editor'e yazarak, çalıştıralım.
Use user
İnsert into merkez
Exec turkcelo
8) İşlem başarı ile tamamlandıktan sonra merkez tablosunu açarak, kayıtları kontrol
edelim.
9) Şimdi daha değişik bir şey yapalım. Aşağıdaki örnekte isimin ilk iki harfini
kopartarak, telefon numarasının ilk dört rakamı ile birleştirerek, isim sütununa yazdıran
Stored Procedure'ü oluşturuyoruz. Diğer sütunları boş bırakıyoruz ve bu seçilen kayıtları,
merkez tablosuna ekliyoruz.
use cuneyt;
go
create proc fantastik as select musterino,upper(SUBSTRING(mad,1,2)),null,null
from musteri
10) Çalıştırdığımızda yeni kayıtlar "merkez" tablosu içine aşağıdaki şekilde
eklenecektir.
11) Bir veri tabanında aynı isimli stored procedure olabilir. Ancak kullanıcı adı farklı
olmak kaydı ile bu gerçekleşebilir. Aşağıda cuneyt adlı kullanıcıya ait fantastik isimli stored
procedure'ü oluşturuyoruz. Tabiki önceden böyle bir kullanıcı olması gerekir. Veya bu isimli
bir Schema tanımlanması lazım. SQL Server 2012 içinde bağımsız şema oluşturulabilir.
create proc fb.fantastik
as
select musterino,upper(SUBSTRING(mad,1,2)),null,null
from musteri
go
STORED PROCEDURE DEĞİŞİKLİĞİ ve SİLME:
Oluşturulan bir stored procedure üzerinde kod ile değişiklik yapılacaksa, ALTER
PROCEDURE ifadesi kullanılır.
Yalnız tavsiye edilen; bir stored procedure'ü direkt olarak değiştirmek yerine, yeni bir
stored procedure'ü oluşturarak; eskisini kopyalayıp onun üzerinde değişiklik yapmaktır.
Değiştireyim derken bozabilirsiniz, onun için bu şekilde yedekli çalışmak, en iyi çözümdür.
Dikkat edilecek noktalar;
* Herhangi bir ekstra seçenek kullanılarak oluşturulmuş stored procedure'ü (Örneğin;
WITH ENCRYPTION) değiştirirken, mutlaka bu seçenekleri tekrar yazmak gerekir.
* ALTER PROCEDURE ifadesi sadece bir stored procedure'e etki eder. Eğer
değiştirdiğiniz stored procedure, başka bir stored procedure tarafından çağrılıyorsa(nested
stored procedure) çağıran stored procedure, bu değişiklikten etkilenmez ve çalışmasında
sorunlar çıkabilir.
* Bu değişikliği yapabilmek için; sysadmin, db_owner veya db_ddladmin sabit rollerine
üye olmak gerekir. En azından ALTER PROCEDURE izninin taşınması gerekir.
Aşağıdaki kod ile daha önce oluşturduğumuz "fantastik" isimli stored procedure içinde
değişiklik yapabiliriz.
alter proc fantastik as select
CONVERT(char(3),musterino)musterino,UPPER(substring(mad,1,2)),null,null
from musteri
go
Bir stored procedure'ü silmek için ise DROP PROC ifadesi kullanılır.
use cuneyt;
go
drop proc fantastik
STORED PROCEDURE OLUŞTURMA KILAVUZU:
Stored Procedure oluştururken dikkat edeceğimiz yapılar;
Tüm Stored Procedure'ların, aynı bağlantı ayarlarını kullanması gerekir. Bunun için
SQL Server; stored procedure oluştururken veya değiştirirken iki ayarı kaydeder. Bunlar:
SET OUOTEDJDENTIFIER ve SET ANSI_NULLS. Bunların seçenekleri ON ve
OFF'dur. ANSI_NULLS; OFF olursa boş olan değerler NULL olarak döner. ON olursa;
hiçbir şey yazmaz. SET OUOTEDJDENTIFIER; String değerleri içinde kullanılan tırnak
işareti durumunu belirtir. Bu değer ON olduğu zaman tanımlamalar; çift tırnak kullanımı
içine alınır ve bilgiler için mutlaka tek tırnak kullanılması gerekir. Eğer OFF olursa;
tanımlayıcılarda tırnak kullanılmaz ve Transact-SQL içinden gelen tüm kurallara uyulması
gerekir.
Bu yapıyı bir örnek ile ifade edersek, sanırım daha iyi anlaşılacaktır.
UYGULAMA:
1) Aşağıdaki kodu yazdığımızda OFF olduğundan, çalışmayacaktır. Hata mesajı
ile karşılaşacağız. Çünkü tablo adını ve sütun adlarını çift tırnak içinde yazdık.
Set QUOTED_IDENTIFIER OFF
GO
CREATE TABLE “personel2” (“sicilno” int IDENTITY,”maas” int)
GO
Hata mesajı;
2) Aşağıdaki yazılımda değeri ON yaptığımız için çalışacaktır. Dikkat edelim,
ifadelerde çift tırnak kullanıyoruz
Set QUOTED_IDENTIFIER OFF
GO
CREATE TABLE “personel2” (“sicilno” int IDENTITY,”maas” int)
GO
DROP TABLE “personel2”
SET QUOTED_IDENTIFIER OFF
3) Aşağıda ise bu kurallar string değerler içinde kullanılmıştır.
set quoted_identifier on
go
create table "personel2"("sicilno" int identity, "maas" int)
go
select "sicilno","maas" from "personel2" order by "maas"
go
drop table "personel2"
set quoted_identifier off
4) Kod çalıştığında sonuç, aşağıdaki gibi olur.
5) Bu ayarları veri tabanı için ON veya OFF pozisyonuna; grafiksel olarak
getirmek için, veri tabanı üzerinde sağ tuşa basarak, Properties seçeneğine tıklanır.
Gelen iletişim kutusundan Options sayfasına geçilir. Burada bulunan ANSI NULL
Default ve Quoted identifiers Enabled seçenekleri kullanılır. Açmak için True, kapatmak
için ise False değerleri seçilir.
Diğer seçenekler; stored procedure tarafından kaydedilemez. Örneğin; SET
ARITHABORT, SET ANSI_WARNING, SET ANSI_PADDING.
*** OBJECTPROPERTY sistem fonksiyonu kullanılarak, seçeneklerin durumunun
ne olduğu öğrenilebilir. Döndürdüğü değer "1" olduğu zaman açık anlamındadır. Aşağıdaki
örnek kod, bir nesnenin adını ve tipini kontrol ederek, ne olduğunu söylemektedir.
if exists (select * from dbo.sysobjects
where id=object_id('[supermanler]') and
objectproperty(id,'isprocedure') = 1)
print 'bu bir stored procedure'
Veya
if OBJECTPROPERTY(object_id('supermanler'),N'isprocedure')=1
print 'bu bir stored procedure'
Eğer koşul doğru ise 'Bu bir stored procedure' ifadesi çıkar
* EXECUTE ifadesi ile bir stored procedure'ü çalıştırmak yerine, sp_executesql sistem
stored procedure'ü ile çalıştırmak, performans açısından daha doğru bir seçimdir.
* Stored Procedure ile ilgili bilgiler syscomments sitem tablosunda tutulur. Bu tablo
içindeki bilgileri silmemiz mümkün değildir. Bu görünüme sp_helptext sistem stored
procedure ile ulaşabiliriz. Ancak stored procedure içine yazdığınız bilgilerin; başkaları
tarafından görünmesini istemiyorsanız, bunun için mutlaka stored procedure oluştururken;
WITH ENCRYPTION seçeneğini kullanmanız gerekir.
create proc fantastiklOOl WITH ENCRYPT10M As select * from müşteriler I
Bu seçeneği kullanarak oluşturulan stored procedure'ün üzerinde sağ tuşa basılınca
Modify seçeneğinin pasif olduğu görünür.
UYGULAMA:
1) Aşağıdaki örnek ile ilk önce, fantastik isimli bir stored procedure varsa onu siliyoruz.
Daha sonra tırnak tanımlamasını kapatıp, boş değer seçeneğini açarak; fantastik isimli bir
stored procedure oluşturuyoruz. Bunun özelliği; müşteriler tablosundaki ilk 5 kaydı seçmesi
ve musterino ya göre büyükten- küçüğe doğru sıralamasıdır.
Son olarak, oluşturduğumuz fantastik isimli stored procedure'ü, exec ifadesi ile
çalıştırıyoruz.
2) çalıştırmak için aşağıdaki ifadeyi kullanalım
USE cuneyt;
GO
IF EXISTS (SELECT * FROM dbo .sysobjects
WHERE id = object_id('fantastik')
and OBJECTPROPERTY(id,'IsFrocedure') = 1)
DROP PROCEDURE [dbo].[fantastik]
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
CREATE PROCEDURE [fantastik]
AS
SELECT TOP 5 * FROM musteri
ORDER BY musterino desc
3) Bir stored procedure içinde yazılı kodları görmek için; sp_helptext sistem stored
procedure'ü kullanılır. Aşağıdaki yazılım ile "fantastik" stored procedure'ün yazılımı
hakkında, bilgi sahibi oluyoruz.
4) Çalıştırılınca çıktısı, aşağıdaki şekildeki gibi olacaktır.
5) Oluşturduğumuz "fantastik" isimli stored procedure'ün ID'sini
öğrenmek için, aşağıda*ki kodu yazmamız gerekir.
6) Ççalıştırınca çıktısı, aşağıdaki gibi bir sayısal değer olacaktır
7) ANSI NULL bağlantı ayarlarının açık olup- olmadığını öğrenmek için
aşağıdaki kodu yazıyoruz. Eğer sonuç "1" çıkarsa, açıktır. Buraya yazılan sayısal değer, bir
önceki adımda bulduğumuz değerdir. Yani,
"fantastik" stored procedure'ünün kimlik numarasıdır.
8) Çalıştırınca "1" çıkıyorsa açık(ON), "0" çıkıyorsa kapalıdır(OFF). Biz
uygulamamızın ilk adımında; SET ANSI_NULLS ON ifadesini kullandığımız için, sonucun
"1" çıkması gerekir.
SELECT OBJECT_ID(fantastik’)
9) Aşağıdaki ifade çift tırnak durumunu kontrol eder
Select objectproperty(2133582639,’ExecIsQuotedIdentOn’)
10) Aşağıdaki yazılımda tırnak özelliği kapatıldığı için, çift tırnak ifadesi içinde ayıraç
işareti olarak, tek tırnak kullanabildik. Yani, Türkiye'nin ifadesini yazabildik.
SET QUOTED_IDENTIFIER OFF
GO
ÜSE cuneyt
CREATE TABLE Test i sicilno int, textdurumu varchar (50) i
GO
INSERT INTO Test VALUES (1,"Türkiye'nin Başkenti Ankara'dır")
GO
SELECT * FROM Test
10) Çalıştırdığımızda test tablosunun içine kaydı, aşağıdaki şekilde ilave edecektir.
11) Ancak SET OUOTEDIDENTIFIER ON yaparak çalıştırdığımızda, bu işlemin
gerçekleşmediğini göreceğiz. Yukarıdaki kodun aynısını yazarak deneyiniz. Ancak ilk önce
test tablosunu silmeyi unutmayınız. Bunun sonucunda, işlemin gerçekleşmeyeceğini bildiren
aşağıdaki mesaj ile karşılaşacaksınız ve tablonun içine hiçbir kaydın eklenmeyeceğini
göreceksiniz.
12) Şimdi bir stored procedure ile son olarak, tırnak olayını kullanalım.
SET QUOTED_IDENTIFIER OFF
--Oluşturumadan önce off yapıyoruz ki tek tırnak olayına uygun olsun.
GO
USE cuneyt
Go
create procedure test3
as
INSERT INTO Test VALUES (2,"Türkiye'nin Başkenti Ankara'dir")
GO
14) Çalıştırmak için, aşağıdaki kodu uyguluyoruz.
INSERT INTO Test2 EXEC test3
15) "Test" isimli tabloyu açarak, verilerin içine kaydedildiğini kontrol ediyoruz.
STORED PROCEDURE İÇİNDE PARAMETRE KULLANIMI:
Stored Procedure'leri daha fonksiyonel olarak kullanmak için, parametreli olarak
tasarlamak gerekir. Örneğin; kitap adına göre sorgulama yapmayı planlıyoruz, eğer direkt
kitap adını sorgulama içine yazarsak, başka bir kitap adı için her seferinde değişiklik
yapmamız gerekir. İşte bu durumda; kitap adını parametre olarak tanımlarsak, sorgulamayı
dinamik olarak kullanabiliriz. Output ve Input olmak üzere, iki adet parametre vardır. Ancak
SQL Server 2012 ile beraber bir üçüncü parametre tipi eklenmiştir ve bunun adı da Table-
Valued' dir.
INPUT PARAMETRE:
Input türü parametreler kullanarak; SQL Server içine bilgilerin geçişini sağlarız.
CREATE PROC ifadesi ile kullanılan bu yazılım, bir veya daha fazla olabilir.
Kullanım biçimi:
©parametre adı veritipi[=default]
Dikkat edilecek noktalar;
* Tüm giriş türlü parametreler, stored procedure başında uygun olup-olmadığı kontrol
edilir.
* Eğer input parametre tanımlarken bir default değer verilmiş ise, o zaman özel bir
değer atamaya gerek yoktur. Parametreler mutlaka bir değer içermeli veya NULL
tanımlaması yapılmalıdır. Bunun dışındaki durumlarda hata oluşur.
* Bir stored procedure içinde en fazla, 2100 adet parametre tanımlanabilir.
* Lokal değişkenlerin sayısı ise hafıza ile sınırlıdır. -
* Parametre adları, sadece o stored procedure için geçerlidir. Aynı isim, başka bir
stored procedure için de kullanılabilir.
* Parametre bilgileri, syscolumns sistem tablosunda tutulur.
Oluşturulan parametreli stored procedure'lerin çalıştırılması için; EXECUTE
stored procedure_adı ifadesinden sonra @parametre_adı=verilecek_değer ifadesi
yazılarak, parametrelere değer atanır.
Kullanım biçimi;
[EXECUTE] procedure_adı
[@parametre_adı=atanacak_değer[OUTPUT][DEFAULT]
[WITH RECOMPLIE]
Ayrıca direkt olarak execute ve stored procedure adından sonra araya, virgül
koyularak parametreler girilebilir. Boş geçilecek değerlere Null yazılmalıdır.
UYGULAMA:
1) "Satis" isimli tablomuzun tasarım kısmına geçerek en üst satıra, "kayitno" isimli
yeni bir sütun ekleyelim ve aşağıdaki Columns kısmından İdentity özelliğini Yes yapalım.
Son olarak kayitno sütunu üzerinde sağ tuşa basarak, Set Primary Key seçeneğine tıklayıp,
bu Constraint'i uygulayalım. Gerek SQL Server içinde, gerekse diğer kullanılan
programlarda sorunsuz olarak Insert, Update ve Delete ifadelerini çalıştırmak için tabloda,
bir Primary Key olması tavsiye edilir.
2) Kayıtların son görünümü, aşağıdaki gibi olmalıdır.
3) "Satis" tablosuna yeni kayıt girişi yapacak Stored Procedure'ü aşağıdaki gibi
tasarlayalım. Burada ilk değer olan kayitno; identity özelliğine sahip olduğu için buna bir
değer atayamayacağız, kendisi otomatik olarak oluşturacak. Ayrıca bize sadece yeni eklenen
kayıdı döndürecek. Bunun için bir sistem fonksiyonu olan @@IDENTITY ifadesinden
yararlanıyoruz. Bu fonksiyon yeni eklenen kayıdın numarasını tutar. Tabii bunu tutması için
o sütunun Identitiy özelliğinin aktif olması gerekir. Biz kayitno sütununda bu özelliği aktif
hale getirmiştik.
use cuneyt;
go
CREATE procedure yenikayit_satis
(
@musterino int, @filmad nvarchar(50), @fiyat int, @alistarih datetime,
@getiristarih datetime)
AS
INSERT INTO satiss(musterino,filmad,fiyat,alistarih,getiristarih) values
(@musterino,@filmad,@fiyat,@alistarih,@getiristarih);
select kayitno,musterino,filmad,fiyat,alistarih,getiristarih from
satiss where(kayitno=@@IDENTITY)
go
4) Bu Stored Procedure'ü çalıştırmak için; exec komutu ile berabe* parametreleri de
belirtmemiz gerekir.
set dateformat dmy
go
exec yenikayit_satis
@musterino=101,
@filmad='misterno',
@fiyat=5,
@alistarih='14/01/2011',
@getiristarih='22/01/11'
5) Bir üstteki yazılım yerine, aşağıdaki şekilde de yazabiliriz. Burada kullandığımız
DATEFORMAT fonksiyonu ile girilecek tarihi gün-ay-yı| biçimine getiriyoruz. Aşağıdaki
yazılımda parametre ismi belirtilmediği için stored procedure içinde bulunan sıraya göre
yazılmalıdır. Oysa bir önceki adımda böyle bir zorunluluk yoktur.
set dateformat dmy
go
exec yenikayit_satis 102,'misterno',5.5,'22/01/2011','25/02/2011'
6) Eğer herhangi bir sütun yerine, hiçbir şey yazmadan geçmek istiyorsak; aşağıdaki
şekilde yazmamız gerekir. Fakat sütunun tasarım kısmında boş geçilebilir(Allow null) izninin
olması gerekir.
Not: ADO .NET için değişken adı ile input parametre değerlerinin avnı olması yararlıdır.
7) Bu işlemler sonucu satis tablomuzun son görüntüsü, aşağıdaki şekilde olacaktır.
8) Boş olan ve olmayan kayıtları aynı anda sorgulamak istersek, aşağıdaki şekilde
yazmamız gerekir. İlk önce ansi_nulls özelliğini on yaparak çalıştıracağız. Aşağıda where
ifadesinden sonraki yazılım, hem on durumunda hem de off durumunda çalışır.
9) Aşağıdaki ifade ise sadece, ansi_nulls özelliği off durumunda iken çalışır.
set ansi_nulls off
select * f rom sat is where
alistarih=Null.
select :
" frorn satis where
alistarih=Null
10) Şimdi var olan bir kayıt üzerinde değişiklik yapan; UPDATE ifadesini kullanalım
CREATE PROCEDURE degistir_satis
(
@musterine int,
(@filmad nvarchar50) ,
@fiyat int,
@alistarih datetime,
@getiristarih datetime,
@Original__kayitno int )
AS
SET MOCOUNT OFF;
UPDATE satis SET
musterino = @musterino,
filmad = @filmad,
fiyat = @fiyat,
alistarih = @alistarih,
getiristarih = @getiristarih
WHERE (kayitno = @Original_kayitno)
11) Aşağıdaki yazılımı kullanarak, ilk kayıdın müşteri numarasını 102, kitabın fiyatını
66 ve adını benten olarak değiştireceğiz.
exec degistir_satis
@musterino=102, @filmad= 'benten ', @fiyat=66,@alistarih=’17/10/2010',
@getiristarih=' 22/10/2010', @Original_kayitno=1)
12) Çalıştırdığımızda ilk kayıt; şekildeki gibi değişikliğe uğrayacaktır.
13) Şimdi var olan bir kayıdı silmek için Delete ifadesini kullanalım. Aşağıdaki ifade,
silmek için gerekli kodu oluşturuyor
CREATE PROCEDURE satis_sil
( @Original_kayitno int
)
AS
DELETE FROM satis WHERE (kayitno = @Original_kayitno)
14) Aşağıdaki yazılım ile 11 numaralı kayıdı siliyoruz.
exec satis_sil
@Original_kayitno-=11
UYGULAMA:
1) Aşağıdaki yazılım müşteriler ve satis tablosunu birleştirerek verdiğimiz film
adına göre kayıtları göstermektedir.
create proc muster_satis2
@fad nvarchar(20)
as
if @fad is null
begin
raiserror('bos deger olamaz',14,1)
return
end
select sati.musterino,
sati.filmad,
musteri.mad,
sati.alistarih,
datename(mm,alistarih) as aylar
from sati inner join musteri on sati.musterino=musteri.musterino
where sati.filmad=@fad
go
2) Çalıştırmak için aşağıdaki kodu yazdığımızda, tablomuzdaki kayıtlara göre aşağıdaki
kaydı görebiliriz.
3) Boş bir film yazıldığında ise şekildeki gibi hata mesajı gelir.
OUTPUT PARAMETER:
Bir Stored Procedure'ü çağırdığımız zaman, içinde bulunan değeri döndürebilir.Bunun
için OUTPUT ifadesi kullanılır.
* Eğer OUTPUT değişkeni bir değer almaz ise, yine de Stored Procedure çalışır, ama
değer fırlatmaz.
* Text ve image dışında herhangi bir veri tipi olabilir.
* Çalıştırırken yine exec komutu kullanılır.
1) Aşağıdaki Stored Procedure, dışarıdan gelen iki değeri hesaplayarak @sonuc isimli
değişkene atıyor. @sonuc değişkeni Output ile tanımlandığı için bu, dışarıya kullanılmak
için gönderilebilir.
create proc carp
@a int,
@b int,
@sonuc int output*
as
set @sonuc=@a*@b
go
2) Çalıştırmak için gerekli yazılım, aşağıdaki gibi olmalıdır.
declare @c int
execute carp
@a=12,
@b=5,
@sonuc=@c output select 'sonuc:',@c
3) Çalıştırıldığı zaman çıktısı, aşağıdaki gibi olacaktır.
TABLE-VALUED PARAMETER:
SQL Server 2012 ile birlikte gelen yeni bir parametre tipi vardır. Bu Table-valued
parameter olarak adlandırılır. Kullanıcı tanımlı tablo tipi i|e deklare edilir. Böylelikle geçici
tablo veya birçok parametre kullanmaya gerek kalmadan, birçok satır kullanılabilir.
UYGULAMA:
1) "ana" isimli tabloyu şekildeki gibi tasarlayarak, içine iki kayıt girelim.
2) Aşağıdaki ifadeleri yazarak çalıştıralım.
USE cuneyt;
GO
CREATE TYPE a1 AS TABLE
( ad VARCHAR(50)
,fiyat INT );
GO
Create PROCEDURE as1
@TVP al READONLY
AS
SET NOCOUNT ON
INSERT INTO ana
([ad]
,[fiyat]
,[durum]
,[tarih])
SELECT *, 0, GETDATE()
FROM @TVP;
GO
3) Test için aşağıdaki ifadeleri yazarak "ana" tabloyu kontrol edelim.
DECLARE @t1
as a1;
insert into @t1(ad,fiyat)
select[ad],0.00
from ana
exec as1 @t1
go
STORED PROCEDURE'LERİN YENİDEN DERLENMESİ:
Stored Procedure normalde bir kez çalıştıktan sonra kendini; Cache içine yerleştirerek,
daha hızlı çalışmayı sağlar. Ancak aşağıdaki durumlarda Stored Procedure' ün yeniden
derlenmesi gerekir.
* Parametreler; Stored Procedure içine geçtikten sonra, çok geniş bir değer
döndürürlerse.
* Stored Procedure için yararlı olabilecek yeni bir index, tabloya eklenirse.
* Parametre değerleri başka tipe dönüşüyorsa.
Yeniden derlemek için, WITH RECOMPILE ifadesi kullanılır. Çalıştırırken Exec
procedure_adı With recompile veya Exec sp_recomplie procedure__adı ifadeleri
kullanılabilir.
Eğer bir Stored Procedure'ün, Cache içinde tutulmasını değil de, her seferinde yeniden
derlenmesini istiyorsak, o zaman With Recompile komutunu kullanırız. Aşağıdaki ifade bunu
sağlar.
use cuneyt
go
create proc yeniden
@a nvarchar(10)
with recompile
as
select COUNT(*) from sati
where filmad=@a
go
Çalıştırmak için aşağıdaki kodu yazalım ve sonucu gözlemleyelim. Eğer tablolarımız
aynı ise "2" değerinin çıkması gerekir.
Exec yeniden ' superman'
Cache içinde bulunan tüm Stored Procedure planlamalarını silmek için, aşağıdaki ifade
kullanılır.
Dbcc freeproccache
HATA MESAJLARI:
Stored Procedure'leri daha etkili kullanmak için; bünyesinde hata mesajları
tanımlanarak bir hata durumunda, kullanıcı bilgilendirilebilir. Bu sadece hata durumlarında
değil, aynı zamanda olumlu durumlarda da tercih edilebilir.
Burada döndürülecek değer; Return ifadesi ile belirlenebilir. Eğer Return değeri "0"
ise işlem başarılı, "0" ile "14" arasında ise aktif kullanılan, "15" ile "99" arası ise gelecekte
kullanılacak değerlerdir. Eğer kullanıcı tanımlı Return değeri desteklenmiyorsa SQL Server,
kendisininkini kullanır.
UYGULAMA:
1) Aşağıdaki örnek, sistem fonksiyonu olan @@rowcount ile satır sayısını
döndürmektedir.
use cuneyt
go
create proc kactane
@f char(10)
as
select * from sati
where filmad=@f
return (@@rowcount)
go
2) Çalıştırmak için, aşağıdaki kodu yazmak yeterlidir.
declare @x int
exec @x=kactane
@f='superman'
print @x
Çıktısı, şekildeki gibi olacaktır.
3) Özel hata mesajı oluşturmak için sp_addmessage system stored procedure'ü
kullanılır.
Böylelikle master tablosu içinde bulunan sysmessages; sistem tablosu içine yazılır.
Ayrıca hata durumu, Windows 2003- 2012 Application log yapısında bulunur.
Aşağıdaki ifade bu yapıya ait bir örnektir.
use master
exec sp_addmessage
@msgnum=50010,
@severity=10,
@msgtext='yapma böyle hatalar',
@with_log='true'
4) Burada kullanılan parametrelerden msgnum ile kayıt numarasını, severity
parametresi ile hatanın türünü ve önemini belirtiyoruz. Bu, çeşitli düzeylerden oluşuyor. Eğer
"10" değerini verirsek bu; kullanıcının yanlış bilgi girişi yaptığı bilgisini, 11- 16 arası
düzeyde ise kullanıcının doğru bilgi girmesini, 17-25 arası ise yazılım ve donanım ile ilgili
hataları gösterir. msgtextı çıkacak mesajı belirler.
Hem Windows hem de SQL log'larına yazılması istenirse, with_log seçeneğinin true
yapılması gerekir.
Master veri tabanı içindeki sysmessages tablosunu sorgulamak için aşağıdaki ifadeyi
yazarak çalıştırdığımızda, tabloda kendi mesajımızın eklenmiş olduğunu görebiliriz.
5) Mevcut bir mesajı değiştirmek için, replace özelliği aşağıdaki gibi kullanılır.
exec sp_addmessage
@msgnum=50010,
@severity=10,
@msgtext='dikkat hatası var',
@with_log='true',
@replace='replace'
Not: Kullanıcı tanımlı mesaj oluşturmak veya bunları değiştirmek için kullanılacak
numaraların, 50000'den büyük olması gerekir. Bu yapılarda yaygın olarak kullanılan diğer bir
sistem fonksiyonu @@error' dur. Bu fonksiyon "0" değerini alırsa hata yok, aksi durumda
hata var anlamındadır.
Diğer bir hata mesajı yapılandırma Raiserror ifadesi ile olur. Kullanıcı tanımlı hata
mesajları kullanılabileceği gibi, direkt bir açıklama da yazılabilir. Bundan sonra mutlaka bir
severity düzeyi ve mesaj durumu sayısal olarak belirtilmelidir. Mesaj durumu 1-127 arası bir
değer alabilir. Bu, destek mühendisleri için bir bilgilendirme olarak kullanılabilir. "-1"
yazılırsa da bu 1 olarak işlem görür yani, varsayılan ayardır.
Eğer mesajın Event viewer içindeki Application log içine yazılmasını istersek, sonuna
With log ifadesi koyabiliriz. Gerçi 0-17 arası değer hata kodunda tanımlanmış ise otomatik
olarak yazar, ancak özel hatalar olan 17 sonrası için kullanmamız gerekir.
Aşağıda, daha önce oluşturduğumuz 50010 numaralı mesajın, Raiserror ile kullanılması
gösterilmiştir.
raiserror(50010,10,1)with log
raiserror(50010,16,1)
raiserror(50010,25,1)with log
raiserror('zor dostum zor',15,1) with log
raiserror(50010,15,1)
Event viewer seçeneğini Administrative Tools içinden açtığımızda bu hata ve bilgi
mesajlarının yazıldığı görülecektir. 13 numaraya kadar olanlar Information şeklinde
yazılırken, 14 Warning, diğerleri ise Error olarak yazılır.
Administrative Tools içinden Event Viewer seçeneğine tıklanıp, Application Log kısmı
seçildiğinde SQL Server tarafından fırlatılan bilgi, uyarı ve hata mesajları görüntülenecektir.
UYGULAMA:
1) Daha önce oluşturduğumuz "müşteriler" tablosunun tasarım kısmına geçerek, "musterino"
sütununa Primary Key koyalım.
2) Bu tablomuzdaki son kayıt durumu, şekildeki gibi olsun.
3) Aşağıdaki hata mesajını oluşturalım.
exec sp_addmessage
@msgnum=50025,
@severity=16,
@msgtext='boyle bir musteri yok',
@with_log='true'
4) Yukarıdaki kodu çalıştırdıktan sonra, Master veri tabanı içinde bulunan;
sysmessages sistem tablosunu sorgulayarak mesajımızın burada oluştuğunu gözlemleyelim.
5) Aşağıdaki Stored Procedure'ü oluşturalım. Bu stored procedure, girilen müşteri
numarası ve yeni telefon numarasına göre, var olan müşterinin telefonunu değiştirecektir.
Eğer müşteri numarası boş bırakılırsa lütfen müşteri numarasını giriniz mesajı, müşterinin
numarası yanlış girilirse böyle bir müşteri yok mesajını verecektir. Her şey doğru ise başarı
ile değişmiştir ifadesini gösterecektir.
create procedure musteri_telefon__degisiklik
@musterino int=null, @mtel varchar (15) =null
as
if @musterino is null
begin
print 'Lütfen Müşteri numarası giriniz'
return
end
if not exists (select * from musteri where musterino=@musterino)
begin
raiserror(50025,16,1)--Böyle bir müşteri yok
return
end
begin transaction
update musteri set mtel=@mtel where musterino=@musterino
select convert (varchar (25),@musterino) + ' noiu müşterinin telefonu' + @mtel+ 'alarak
babari ile degismistir '
commit transaction
6) Aşağıdaki şekillerde stored procedure'ü çalıştırarak, çıkan sonuçları
Gözlemleyelim. İlk ikisinde işlem gerçekleşmeyecek, üçüncüde ise başarı jle gerçekleşerek;
101 numaralı müşterinin telefonunu değiştirecektir.
exec musteri_telefon__degisiklik
@musterino=null,
@mtel='05367370566'
7) Gerçekten de müşteriler tablosunu açtığımızda, bu değişikliğin olduğunu
göreceğiz.
Bu bölümde son iki konuda anlattığımız yapılar hakkında uygulamalar geliştirerek,
bilgilerin daha iyi oturmasını sağlayacağız. Bunları mutlaka uygulayınız.
VİEW ve STORED PROCEDURE UYGULAMALARI
UYGULAMA:
SENARYO: cuneyt veri tabanı içinde satış tablosunu temel alarak bir Stored
Procedure'ü aşağıdaki gibi geliştiriyorsun. Buradaki amaç, film adlarını verince, yıl sonu satış
raporlarını göstermek.
CREATE PROCEDURE satisrapor
@filmad varchar(8), @toplamciro money OutPUT
AS
SELECT @toplamciro = SUM(fiyat)
FROM satis
WHERE filmad=@filmad
IF @toplamciro > 0
RETURN(1)
RETURN(0)
1) Yukarıdaki kod ile dışarıdan girilen film adını @filmad isimli değişken yakalıyor,
satis tablosundan bu bilgiye uyan fiyat bilgisini @toplamciro isimli Output
değişkene atıyor. Eğer bunun sonucunda bir toplam değeri oluşmuş ise 1, sıfır olarak
kalmış ise 0 değerini döndürüyor. Sıfır olarak kalınca "demek ki öyle bir film yok"
anlamına geliyor.
2) Sen bu Stored Procedure'ü çalıştırdığın zaman, eğer verdiğin film adı veri tabanında
bulunuyorsa; bu filmin yılsonu toplam cirosunu göstersin. Ancak bulunmuyorsa yani 0
değerini döndürüyorsa "Film Bulunamadı" mesajını çıkarmasını istiyorsun.
Bunun için çalıştırma yazılımını nasıl yaparsın?
3) ÇÖZÜM: Burada dönen değerleri bir lokal değişkene aktararak bu lokal değişkeni
sorgulamak, en doğru çalıştırma şekli olacaktır. Bu bilgiler göz önüne alınarak, yazılım
aşağıdaki gibi olmalıdır.
DECLARE @gelen int
DECLARE @sonuc money
EXEC @gelen=satisrapor '2012', @sonuc output
if @gelen=0
print 'kitap bulunamadı'
else
begin
print 'bu kitabın yılsonu satisi : '
print convert(varchar(15),@sonuc) + 'yil'
end
go
Yukarıdaki yazılımı yorumlayacak olursak;
* @gelen ve @sonuc isimli iki lokal değişken tanımlıyoruz.
* Stored procedure'ü çalıştırırken 2012 isimli filmi sorguluyoruz ve fırlatacak değeri
sonuna koyduğumuz @sonuc değişkenine atarken, fonksiyonun döndüreceği değeri yani 0
veya 11 @gelen isimli değişkene atıyoruz.
* Eğer @gelen sıfıra eşitse yani 0 ise "Film Bulunamadı" mesajını çıkartırken, aksi
durumda ön açıklama bilgisi ile birlikte ekrana yansıtıyoruz.
4) Kodu çalıştırdığımızda görüntü, şekildeki gibi olacaktır.
UYGULAMA:
1)SENARYO: Online kitap satışı yapmak için bir yapı tasarlamak istiyorsun.
Müşteriler kitap siparişini, Web sitesini kullanarak yapacaklar. Verilen siparişler yüksel veri
tabanı içindeki kitapsiparis isimli tabloya yazılacak. Ancak sen bu gelen bilgilerden
bazılarını raporlar isimli bir tabloya aktaracaksın ve bu tabloyu da internet ortamında
yayımlayacaksın. Bunun için gerekli Stored Procedure yapısını nasıl oluşturursun.
2)ÇÖZÜM: İlk olarak bu iki tabloyu aşağıdaki şekilde tasarlarım.
Bu tablodan sadece kitapad ve adet bilgilerinin kopyalanacağı diğer tablo tasarımını
ise şekildeki gibi yapalım.
İçlerine hiçbir kayıt girmeyelim.
3)Tablolara veri girişi sağlayacak, bir Stored Procedure hazırlayalım.
create procedure siparis2
@musterino int,
@musteriad varchar (40),
@kitapad varchar(40),
@fiyat money,
@musteritel varchar (40),
@adet int
as
insert into kitapsiparis values
(@musterino,@musteriad,@kitapad,@fiyat,@musteritel,@adet)
insert into raporlar values (@kitapad,@fiyat)
4)Ardından aşağıdaki şekilde çalıştıralım.
exec siparis 104,'yuksel inan','c# 2010',40,'3333333',5
exec siparis 107,'yuksel inan','ASP.NET 2010',45,'2222222',12
5)Tabloları açarak, içine kayıtların yazıldığını gözlemleyelim.
UYGULAMA:
1) SENARYO: Şirketin veri tabanı yöneticisisin. Veri tabanı içinde "Satışlar" isimli bir
tablo var ve yaklaşık 2 milyon satıra sahip. Bu tablo, şirket içinde bulunan tüm
bölümlere ait satış bilgilerini içermektedir. Her bölüm bu tablo içinde bulunan
BölümNo sütununda tanımlanmıştır. Uyguladığın sorgulamalarda bir bölümü istemene
karşın, tüm bilgileri tarıyor.
Bu sorguların l/O performansını arttırmak istiyorsun fakat, uygulamaların tabloyu
açışında bir değişiklik yapmak daha doğrusu; uygulamaların etkilenmesini istemiyorsun. Ne
yapman gerekir?
2)ÇÖZÜM: Bu kadar kayıt varsa, bu tabloyu parçalara ayırmak gerekir.
Bunun için aşağıdaki işlemleri yaparım.
* Her bir bölüm için, yeni bir tablo oluştururum.
* Her bölüme ait satış bilgilerini Satışlar tablosundan, kendilerine ait olan tablonun
içine taşırım.
* Yeni tabloların BölümNo sütununa, bir CHECK Constraint'i koyarım.
* Yeni tablolarla ilgili bir View oluştururum.
3) SENARYO: Bir veri tabanı yöneticisisin. Oturup, temizlik yapmaya karar verdin©
ve SQL Server içinde kullanılmayan eski nesneleri silmek istiyorsun. Eski bir View gördün
adı "1997" ve silmeye çalıştın ancak, silemedin.
Araştırmaların sonucu şu bilgileri edindin;
*** Bir Clustered lndex var.
*** Bu View üzerinde gerekli hakkın var.
*** View içinde WITH SCHEMABINDING kullanılmış.
*** View oluşumunda bir in-line fonksiyon kullanılmış.
*** INSTEAD OF Trigger tanımlanmış,
4) Ne yapman gerekir?
5) ÇÖZÜM: Burada sıralanan maddelerden hiçbiri View silinmesini engellemez.
Demek ki fonksiyon içinde WITH SCHEMABINDING var. Onun için bu fonksiyonu adam
etmek gerekir. Yani, içindeki WITH SCHEMABINDING silinmesi gerekir.
6)Bir View oluşturulurken WITH SCHEMABINDING aşağıdaki şekilde View ile
ilişkilendirilir.
create view satis8
with schemabinding
as
select filmad,fiyat from dbo.satis
where filmad = 'superman'
7) SENARYO: Bir oyuncak üreticisinin veri tabanı yöneticisisin. Şirkette çalışanlar
idareci, yönetici ve çalışan olarak üç kategoriye ayrılmış. Şirketin intranet Web ana
sayfasında bu üç pozisyona ait haberler tasarlanmış durumdadır. Bir kullanıcı Log On olunca,
kendi pozisyonuna ait haberleri izleyebiliyor.
Şirket haberleri "haberler" isimli tablo içinde tutuluyor. Kullanıcılar bu tablo içindeki
bilgileri sadece görebilecek, fakat değişiklik yapamayacak ayrıca, kendi bölümüne ait verilere
ulaşacak. Bunun için ne yapman gerekir?
8)ÇÖZÜM: Bu yapı için en uygun Stored Procedure oluşturmaktır. Tablo içinde
bulunan kategori bilgisine bir parametre gönderilerek ve SELECT ifadesi kullanılarak sadece
kendine ait bilgilere ulaşması sağlanır.
UYGULAMA:
1) SENARYO: Sen danışmanlık hizmeti sağlayan bir şirketin veri tabanı danışmanısın..
Bu şirket elemanlarına ait bilgiler, aşağıdaki şekilde oluşturulmuş "personelim" isimli tabloda
tutuyor.
create table personeller
(
perno int not null,
pertip char (1) not null,
perad varchar(50),
adres varchar(50) null,
telefon varchar(20) null,
constraint PK_perno primary key (perno))
2) Bu tabloda bulunan pertip isimli sütunda çalışanların vasıfları belirleniyor. Bunlar
yönetici, danışman, sekreter gibi bilgiler içeriyor. En üst yönetici olan yöneticilere; danışman
grubunda bulunan elemanlar dışında bu tablodaki kayıtlar üzerinde değişiklik yapma, yeni
kayıt ekleme ve silme yetkisi vermek istiyorsun nasıl yaparsın?
3) ÇÖZÜM: Aşağıdaki şekilde kayıtları gireriz. Burada 1 numara yönetici, 2 numara
sekreter, 3 numara danışman kategorisinde çalışanları göstermektedir.
4) Aşağıdaki şekilde WITH CHECK OPTION parametresi ile oluşturduğumuz View'da,
3 no'lu kayıtlar için yapılandırma yapılmasını engelliyoruz.
create PROCEDURE StokGuncel
@stokno int,
@fiyat money
AS
BEGIN
DECLARE @hatano int, @say int, @Msg varchar (50)
UPDATE stoklar SET fiyat=@fiyat
WHERE stokno=@stokno AND fiyat<>@fiyat
SELECT @say=@@ROWCOUNT
If @say = 0
RAISERROR ('Hata kodu %d ,
Güncellenemeyen Stok No %d.', 10, 1, @say, @stokno) WITH log
ELSE
SELECT 'Stok numarası' + STR (@stokno) + ' olanın yeni fiyatı ' + STR
(@fiyat) + '.'
END
5) Elemanlar isimli View'ı açıp, pertip kısmına 3 yazarak yeni bir kayıt girmeye
kalktığımızda, izin vermeyecektir. Ancak diğer pertip bilgilerini kullanarak, kayıt girebiliriz.
Bu kural; değişiklik ve silme için de geçerli olacaktır.
UYGULAMA:
1)SENARYO: Bir firmanın veri tabanı geliştiricisisin. Eski Stok fiyatları
güncellenirken bir hata meydana geldiğinde, bu hatanın da günlüğünün(log) tutulması ve
Client uygulamasına hata mesajının dönmesi gerekiyor.
Bu yapıyı sağlayacak planlamayı nasıl yaparsın?
1) ÇÖZÜM: Stoklar tablosunu şekildeki gibi, tasarlayalım.
İçine şekildeki kayıtları girelim.
2) Esas sorumuzun cevabını oluşturan Stored Procedure'ü aşağıdaki gibi
oluşturalım.
Bu Stored Procedure'ü analiz edecek olursak;
* Dışarıdan girilen parametreler @stokno ve @fiyat değişkenleri tarafından
yakalanıyor.
* Stoklar tablosunu, bu iki değere bakarak güncellemeye çalışıyor.
* Eğer bir hata olursa RAISERROR ile bunu hem kullanıcıya, hem de Event Viewer
içine fırlatıyoruz.
*** Eğer işlem başarı ile gerçekleşirse, bu bilgiyi sunuyoruz.
3) Test etmek için, aşağıdaki kodu yazalım;
4) Kodu çalıştırdığımızda aşağıdaki mesaj ile karşılaşırız. Aynı zamanda tablo içine
baktığımızda, değerin değiştiğini görebiliriz.

More Related Content

What's hot

İleri Seviye T-SQL Programlama - Chapter 11
İleri Seviye T-SQL Programlama - Chapter 11İleri Seviye T-SQL Programlama - Chapter 11
İleri Seviye T-SQL Programlama - Chapter 11Cihan Özhan
 
Kullanici tanimli fonksi̇yons
Kullanici tanimli fonksi̇yonsKullanici tanimli fonksi̇yons
Kullanici tanimli fonksi̇yonsoktaygokgol
 
Oracle 12c Database In-Memory
Oracle 12c Database In-MemoryOracle 12c Database In-Memory
Oracle 12c Database In-MemoryGokhan Atil
 
progressokulu.com Advanced Business Language Slide 10
progressokulu.com Advanced Business Language Slide 10progressokulu.com Advanced Business Language Slide 10
progressokulu.com Advanced Business Language Slide 10kaan verdioglu
 

What's hot (6)

Extjs 4 education
Extjs 4 educationExtjs 4 education
Extjs 4 education
 
İleri Seviye T-SQL Programlama - Chapter 11
İleri Seviye T-SQL Programlama - Chapter 11İleri Seviye T-SQL Programlama - Chapter 11
İleri Seviye T-SQL Programlama - Chapter 11
 
Kullanici tanimli fonksi̇yons
Kullanici tanimli fonksi̇yonsKullanici tanimli fonksi̇yons
Kullanici tanimli fonksi̇yons
 
Flotranagiris
FlotranagirisFlotranagiris
Flotranagiris
 
Oracle 12c Database In-Memory
Oracle 12c Database In-MemoryOracle 12c Database In-Memory
Oracle 12c Database In-Memory
 
progressokulu.com Advanced Business Language Slide 10
progressokulu.com Advanced Business Language Slide 10progressokulu.com Advanced Business Language Slide 10
progressokulu.com Advanced Business Language Slide 10
 

Viewers also liked

8.hafta yusuf dinçer
8.hafta yusuf dinçer8.hafta yusuf dinçer
8.hafta yusuf dinçeroktaygokgol
 
Sql serverda indexkavrami
Sql serverda indexkavramiSql serverda indexkavrami
Sql serverda indexkavramioktaygokgol
 
Metin gülyüz aralık kişilik sahibi olma
Metin gülyüz aralık kişilik sahibi olmaMetin gülyüz aralık kişilik sahibi olma
Metin gülyüz aralık kişilik sahibi olmaoktaygokgol
 
7.hafta kadir dikmen
7.hafta kadir dikmen7.hafta kadir dikmen
7.hafta kadir dikmenoktaygokgol
 
Sosyal Yaşamda Etkili İletişim
Sosyal Yaşamda Etkili İletişimSosyal Yaşamda Etkili İletişim
Sosyal Yaşamda Etkili İletişimSadullah M. Bağ
 
Veri̇ tabani kurtarma i̇şlemleri̇ sunu
Veri̇ tabani kurtarma i̇şlemleri̇ sunuVeri̇ tabani kurtarma i̇şlemleri̇ sunu
Veri̇ tabani kurtarma i̇şlemleri̇ sunuoktaygokgol
 
özet - Etkili i̇letişim ve sağlıklı i̇lişkiler
özet - Etkili i̇letişim ve sağlıklı i̇lişkiler özet - Etkili i̇letişim ve sağlıklı i̇lişkiler
özet - Etkili i̇letişim ve sağlıklı i̇lişkiler Ayda Eris
 
Ms sql server architecture
Ms sql server architectureMs sql server architecture
Ms sql server architectureAjeet Singh
 

Viewers also liked (15)

8.hafta yusuf dinçer
8.hafta yusuf dinçer8.hafta yusuf dinçer
8.hafta yusuf dinçer
 
Sql serverda indexkavrami
Sql serverda indexkavramiSql serverda indexkavrami
Sql serverda indexkavrami
 
Itt
IttItt
Itt
 
Sunu
SunuSunu
Sunu
 
8.hafta
8.hafta8.hafta
8.hafta
 
Sunu
SunuSunu
Sunu
 
Metin gülyüz aralık kişilik sahibi olma
Metin gülyüz aralık kişilik sahibi olmaMetin gülyüz aralık kişilik sahibi olma
Metin gülyüz aralık kişilik sahibi olma
 
7.hafta kadir dikmen
7.hafta kadir dikmen7.hafta kadir dikmen
7.hafta kadir dikmen
 
Ittodev
IttodevIttodev
Ittodev
 
Sosyal Yaşamda Etkili İletişim
Sosyal Yaşamda Etkili İletişimSosyal Yaşamda Etkili İletişim
Sosyal Yaşamda Etkili İletişim
 
Hayrettin kunuk
Hayrettin kunukHayrettin kunuk
Hayrettin kunuk
 
Konu anlatımı
Konu anlatımıKonu anlatımı
Konu anlatımı
 
Veri̇ tabani kurtarma i̇şlemleri̇ sunu
Veri̇ tabani kurtarma i̇şlemleri̇ sunuVeri̇ tabani kurtarma i̇şlemleri̇ sunu
Veri̇ tabani kurtarma i̇şlemleri̇ sunu
 
özet - Etkili i̇letişim ve sağlıklı i̇lişkiler
özet - Etkili i̇letişim ve sağlıklı i̇lişkiler özet - Etkili i̇letişim ve sağlıklı i̇lişkiler
özet - Etkili i̇letişim ve sağlıklı i̇lişkiler
 
Ms sql server architecture
Ms sql server architectureMs sql server architecture
Ms sql server architecture
 

Similar to 9.hafta cüneyt tomruk

Veri̇ tabani oluşturma ve yapilandirma
Veri̇ tabani oluşturma ve yapilandirmaVeri̇ tabani oluşturma ve yapilandirma
Veri̇ tabani oluşturma ve yapilandirmaoktaygokgol
 
DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...
DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...
DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...atifceylan
 
İleri Seviye T-SQL Programlama - Chapter 09
İleri Seviye T-SQL Programlama - Chapter 09İleri Seviye T-SQL Programlama - Chapter 09
İleri Seviye T-SQL Programlama - Chapter 09Cihan Özhan
 
DATABASEI ARCHIVE MODA ALMA
DATABASEI ARCHIVE MODA ALMADATABASEI ARCHIVE MODA ALMA
DATABASEI ARCHIVE MODA ALMAAnar Godjaev
 
İleri Seviye T-SQL Programlama - Chapter 16
İleri Seviye T-SQL Programlama - Chapter 16İleri Seviye T-SQL Programlama - Chapter 16
İleri Seviye T-SQL Programlama - Chapter 16Cihan Özhan
 
İleri Seviye T-SQL Programlama - Chapter 14
İleri Seviye T-SQL Programlama - Chapter 14İleri Seviye T-SQL Programlama - Chapter 14
İleri Seviye T-SQL Programlama - Chapter 14Cihan Özhan
 
Veri̇tabani ve Kullanici Yöneti̇mi̇
Veri̇tabani ve Kullanici Yöneti̇mi̇Veri̇tabani ve Kullanici Yöneti̇mi̇
Veri̇tabani ve Kullanici Yöneti̇mi̇Anar Godjaev
 
isletim systemi
isletim systemiisletim systemi
isletim systemiIlker Şen
 
Orneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdan
Orneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdanOrneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdan
Orneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdanAnar Godjaev
 
Oracle database architecture
Oracle database architectureOracle database architecture
Oracle database architectureHızlan ERPAK
 
Oracle 12c Database In Memory DBA SIG
Oracle 12c Database In Memory DBA SIGOracle 12c Database In Memory DBA SIG
Oracle 12c Database In Memory DBA SIGGokhan Atil
 
İleri Seviye T-SQL Programlama - Chapter 07
İleri Seviye T-SQL Programlama - Chapter 07İleri Seviye T-SQL Programlama - Chapter 07
İleri Seviye T-SQL Programlama - Chapter 07Cihan Özhan
 
Sql egitimi-gaziantep
Sql egitimi-gaziantepSql egitimi-gaziantep
Sql egitimi-gaziantepsersld61
 

Similar to 9.hafta cüneyt tomruk (20)

Veri̇ tabani oluşturma ve yapilandirma
Veri̇ tabani oluşturma ve yapilandirmaVeri̇ tabani oluşturma ve yapilandirma
Veri̇ tabani oluşturma ve yapilandirma
 
DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...
DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...
DBA ve Geliştiriciler İçin Başarımı Artırıcı Öneriler - PostgreSQL Konferansı...
 
İleri Seviye T-SQL Programlama - Chapter 09
İleri Seviye T-SQL Programlama - Chapter 09İleri Seviye T-SQL Programlama - Chapter 09
İleri Seviye T-SQL Programlama - Chapter 09
 
DATABASEI ARCHIVE MODA ALMA
DATABASEI ARCHIVE MODA ALMADATABASEI ARCHIVE MODA ALMA
DATABASEI ARCHIVE MODA ALMA
 
Recep rapor 3 sunu
Recep rapor 3 sunuRecep rapor 3 sunu
Recep rapor 3 sunu
 
Recep rapor 3 sunu
Recep rapor 3 sunuRecep rapor 3 sunu
Recep rapor 3 sunu
 
İleri Seviye T-SQL Programlama - Chapter 16
İleri Seviye T-SQL Programlama - Chapter 16İleri Seviye T-SQL Programlama - Chapter 16
İleri Seviye T-SQL Programlama - Chapter 16
 
Java EE Struts
Java EE StrutsJava EE Struts
Java EE Struts
 
İleri Seviye T-SQL Programlama - Chapter 14
İleri Seviye T-SQL Programlama - Chapter 14İleri Seviye T-SQL Programlama - Chapter 14
İleri Seviye T-SQL Programlama - Chapter 14
 
Veri̇tabani ve Kullanici Yöneti̇mi̇
Veri̇tabani ve Kullanici Yöneti̇mi̇Veri̇tabani ve Kullanici Yöneti̇mi̇
Veri̇tabani ve Kullanici Yöneti̇mi̇
 
isletim systemi
isletim systemiisletim systemi
isletim systemi
 
Orneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdan
Orneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdanOrneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdan
Orneklere Oracle 11gR2 ve Genel Kavramlar Isimli kitabdan
 
Sunu
SunuSunu
Sunu
 
Oracle database architecture
Oracle database architectureOracle database architecture
Oracle database architecture
 
Junit
JunitJunit
Junit
 
Oracle 12c Database In Memory DBA SIG
Oracle 12c Database In Memory DBA SIGOracle 12c Database In Memory DBA SIG
Oracle 12c Database In Memory DBA SIG
 
İleri Seviye T-SQL Programlama - Chapter 07
İleri Seviye T-SQL Programlama - Chapter 07İleri Seviye T-SQL Programlama - Chapter 07
İleri Seviye T-SQL Programlama - Chapter 07
 
Sql egitimi-gaziantep
Sql egitimi-gaziantepSql egitimi-gaziantep
Sql egitimi-gaziantep
 
Delphi 7
Delphi 7Delphi 7
Delphi 7
 
PostgreSQL Hem Güçlü Hem Güzel!
PostgreSQL Hem Güçlü Hem Güzel!PostgreSQL Hem Güçlü Hem Güzel!
PostgreSQL Hem Güçlü Hem Güzel!
 

9.hafta cüneyt tomruk

  • 1. STORED PROCEDURE Transact-SQL ifadelerinin bir arada kullanılmasından oluşturulan yapılara Stored Procedure adı verilir. Stored Procedure farklı yapılarda bulunur.  System Stored Procedure(sp_): Bu tür procedure'ler, master veri tabanı içinde tutulur ve genellikle sistem tabloları hakkında bilgi döndürmek için kullanılır. Genel olarak sp ifadesi ile başlar. Herhangi bir veri tabanı içinde çalıştırılabilir.  Local Stored Procedure: Kullanıcı veri tabanları içinde, özel olarak tanımlanan stored procedure'lerdir.  Temporary Stored Procedure: Geçici olarak oluşturulan stored procedure'lerdir. İki ayrı yapısı vardır. Sadece belli bir veri tabanında kullanılanlar ve tüm veri tabanlarında kullanılanlar. Lokalde kullanılanların ismi # ile başlarken, diğeri ## ile başlar.  Remote Stored Procedure: SQL Server'ın eski bir kullanımı olan bu yapı, dağıtılan(distributed) sorgulamalarda kullanılmaktadır.  Extended Stored Procedure(xp_): DLL'ler tarafından, SQL Server dışında kullanılan stored procedure'lerdir. Genellikle xp ifadesi ile başlayan bu tür stored procedure'ler, bazı system stored procedure'leri tarafından da çağrılarak kullanılabilir. SQL Server içindeki Stored Procedure diğer programlama dillerine benzer; * Diğer stored procedure'leri çağırabilir. * Dışarıdan değer alabilir. * İçinden çağrılan değer; başarılı veya başarısız olarak dönebilir. * Birden fazla değeri, dışarıya yollayabilir. Kısacası, Transact-SQL komutlarını kullanarak yapılan programlama olarak ifade edebiliriz. Ayrıca uygulama yazılımları tarafından aynı anda kullanılması, veri tabanı yapısını gizlemesi, güvenlik mekanizmasının gelişmiş olması, performansı arttırması ve network trafiğini azaltması sayılabilecek diğer avantajlarındandır. STORED PROCEDURE YAPILANDIRMASI: Bu kısımda artık işe başlıyoruz ve nasıl Stored Procedure oluşturulacağını, çalıştırılacağını, değiştirileceğini ve silineceğini detaylı olarak inceleyeceğiz.
  • 2. STORED PROCEDURE NASIL OLUŞTURULUR? Stored Procedure, aktif veri tabanı içinde oluşturulur. Sadece geçici stored procedure'ler tempdb veri tabanı içinde tutulur. Stored procedure oluşturma formatı, view oluşturma formatına benzer. CREATE PROCEDURE ifadesi ile oluşturulur. Stored Procedure oluştururken aşağıdaki kurallara ve önerilere dikkat etmek gerekir. * Stored Procedure içinde; tablo, view, kullanıcı tanımlı fonksiyon ve diğer stored procedure'ler, aynı zamanda geçici tablolar da kullanılabilir. * CREATE PROCEDURE tanımlaması, sınırsız sayıda ve tipte Transact-SQL ifadesi içerebilir. Ancak beraber kullanılamayacak ifadelerde vardır. Bunlar; CREATE DEFAULT CREATE PROCEDURE CREATE RULE CREATE TRIGGER CREATE VIEW * CREATE PROCEDURE ifadesini kullanmak için, aşağıdaki haklara veya gruplara üye olmak gerekir. sysadmin db_owner db_ddladmin Veya CREATE PROCEDURE iznine sahip olmalı. * Bir stored procedure'ün en fazla boyutu 128 MB olabilir. Kullanım biçimi; CREATE PROC[EDURE] procedure_adı[;sayı] [{@parametre_adı veri tipi] [WARNING][=default][OUTPUT]][,n] [WITH{RECOMPLIE|ENCRYPTION|RECOMPLIE,ENCRYPTION}] [FOR REPLICATION] AS sqljfadesi[leri] UYGULAMA: 1) Bu konumuzda, bir önceki konuda oluşturduğumuz müşteriler ve satis tablolarını kullanacağız. Bu tabloda hiçbir index ve kısıtlama olmadığına emin olduktan sonra, aşağıdaki kayıtların bulunduğunu kontrol ediniz.
  • 3. 2) SQL Server Query Editör içine aşağıdaki ifadeleri yazalım. Bu kod superman isimli filmleri listeleyecektir. Use user Go Create proc supermanler As Select * from satis Where filmad=’superman’ go 3) Oluşturduğumuz supermanler isimli stored procedure'ü çalıştırmak için, aşağıdaki gibi exec komutu kutlanılır. Use cuneyt Exec supermanler 4) Bunun sonucunda; sadece film adı superman olan kayıtlar listelenecektir. Bizim örneğimizde, bu sorgulamaya uyan iki kayıt vardır.
  • 4. 5) Oluşan Stored Procedure'ü görmek için; veri tabanı altında bulunan ProgrammabilityStored Procedures nesnesini kullanabiliriz. Ayrıca yazdığımız kodu görmek veya üzerinde değişiklik yapmak için, oluşturduğumuz stored procedure üzerinde sağ tuşa basarak, Modify seçeneğine tıklamamız yeterlidir. Yine bu Stored Procedure'ü buradaki Execute Stored Procedure seçeneği ile çalıştırabiliriz. 1) Modify seçeneğine tıkladığımızda, şekildeki yapı karşımıza gelir. Burada değişiklik yapabiliriz. 2) Grafiksel olarak Stored Procedure oluşturmak; çok fazla avantaj sağlamaz, ama yine de basit bir stored procedure'ü grafiksel olarak Object Explorer içinden oluşturmak istersek, veri tabanı altında bulunan ProgrammabilityV Stored Procedures nesnesi üzerinde sağ tuşa basarak, New Stored Procedure seçeneğine tıklarız. 3) Gelen ekran; standart bazı yazılar içerir.
  • 5. 4) Aşağıdaki ifade Kasım 2010 yılı ile bugünkü tarih arasında satılan filmleri gösteren stored procedure'ü oluşturur. EXECUTE STORED PROCEDURE: Daha önce de belirttiğimiz gibi bir stored procedure, exec komutu ile çalıştırılır. Ayrıca bir INSERT ifadesinin parçası olarak da çalıştırılabilir. Kullanım sekli: [EXECUTE] [@ dönen_durum=] {procedure_adı[;sayı]} [[parametre)]{değer|@değişken[OUTPUTJ|[DEFAULT]] [WITH RECOMPLIE] INSERT ifadesinin kullanım şekli; insert into tablo_adı exec storedprocedure_adı UYGULAMA 1) Aşağıdaki kodu SQL Query Editör içine yazarak, satis tablosuna iki kayıt ekleyen stored procedure'ü oluşturalım.
  • 6. USE user go create proc yenisatisekle as insert into sati values(105,'Hulk',88,'01/22/2011','01/25/2011') insert into sati values(106,'Hulk',99,'01/23/2011','01/27/2011') go 2) Yukarıdaki yazılımı çalıştırdığımızda, sadece yenisatisekle isimli bir stored procedure oluşturur. Kesinlikle bu kodu çalıştırmak, satis tablosuna bir ilave yapmaz. Ekleme yapması için oluşan stored procedure aşağıdaki şekilde çalıştırılmalıdır. 3) satis tablosunu açtığımız zaman görüntü, aşağıdaki gibi olacaktır. 4) Şimdi de INSERT ifadesi ile beraber Stored Procedure'ü nasıl' çalıştıracağımızı inceleyelim Aşağıdaki şekilde "merkez" isimli yeni bir tablo oluşturalım ve içine hiçbir veri girmeyelim
  • 7. 5) Şimdi, müşteriler içinde 0532 ile başlayan telefonları seçen "turkcelo" isimli bir Stored Procedure oluşturalım. create proc turkcelo as select * from musteri where mtel like '0532%' 6) turkcelo isimli stored procedure'ü, aşağıdaki gibi yazarak çalıştıralım. Bunun sonucunda, şekildeki gibi sadece 0532 ile başlayan telefon numaraları listelenecektir Exec turkcelo 7) Şimdi esas yapmamız gereken işi yapalım, turkcelo stored orocedure'ü, 0532 ile başlayan telefon numaralarını seçiyor. Biz bu özelliği kullanarak 0532 ile başlayan telefona sahip kayıtları; yeni oluşturduğumuz merkez isimli tabloya kopyalayacağız ve bunun için stored procedure'ü aşağıdaki gibi INSERT ifadesi ile çalıştıracağız. Aşağıdaki kodu, SQL Server Query Editor'e yazarak, çalıştıralım. Use user İnsert into merkez Exec turkcelo
  • 8. 8) İşlem başarı ile tamamlandıktan sonra merkez tablosunu açarak, kayıtları kontrol edelim. 9) Şimdi daha değişik bir şey yapalım. Aşağıdaki örnekte isimin ilk iki harfini kopartarak, telefon numarasının ilk dört rakamı ile birleştirerek, isim sütununa yazdıran Stored Procedure'ü oluşturuyoruz. Diğer sütunları boş bırakıyoruz ve bu seçilen kayıtları, merkez tablosuna ekliyoruz. use cuneyt; go create proc fantastik as select musterino,upper(SUBSTRING(mad,1,2)),null,null from musteri 10) Çalıştırdığımızda yeni kayıtlar "merkez" tablosu içine aşağıdaki şekilde eklenecektir.
  • 9. 11) Bir veri tabanında aynı isimli stored procedure olabilir. Ancak kullanıcı adı farklı olmak kaydı ile bu gerçekleşebilir. Aşağıda cuneyt adlı kullanıcıya ait fantastik isimli stored procedure'ü oluşturuyoruz. Tabiki önceden böyle bir kullanıcı olması gerekir. Veya bu isimli bir Schema tanımlanması lazım. SQL Server 2012 içinde bağımsız şema oluşturulabilir. create proc fb.fantastik as select musterino,upper(SUBSTRING(mad,1,2)),null,null from musteri go STORED PROCEDURE DEĞİŞİKLİĞİ ve SİLME: Oluşturulan bir stored procedure üzerinde kod ile değişiklik yapılacaksa, ALTER PROCEDURE ifadesi kullanılır. Yalnız tavsiye edilen; bir stored procedure'ü direkt olarak değiştirmek yerine, yeni bir stored procedure'ü oluşturarak; eskisini kopyalayıp onun üzerinde değişiklik yapmaktır. Değiştireyim derken bozabilirsiniz, onun için bu şekilde yedekli çalışmak, en iyi çözümdür. Dikkat edilecek noktalar; * Herhangi bir ekstra seçenek kullanılarak oluşturulmuş stored procedure'ü (Örneğin; WITH ENCRYPTION) değiştirirken, mutlaka bu seçenekleri tekrar yazmak gerekir. * ALTER PROCEDURE ifadesi sadece bir stored procedure'e etki eder. Eğer değiştirdiğiniz stored procedure, başka bir stored procedure tarafından çağrılıyorsa(nested stored procedure) çağıran stored procedure, bu değişiklikten etkilenmez ve çalışmasında sorunlar çıkabilir. * Bu değişikliği yapabilmek için; sysadmin, db_owner veya db_ddladmin sabit rollerine üye olmak gerekir. En azından ALTER PROCEDURE izninin taşınması gerekir. Aşağıdaki kod ile daha önce oluşturduğumuz "fantastik" isimli stored procedure içinde
  • 10. değişiklik yapabiliriz. alter proc fantastik as select CONVERT(char(3),musterino)musterino,UPPER(substring(mad,1,2)),null,null from musteri go Bir stored procedure'ü silmek için ise DROP PROC ifadesi kullanılır. use cuneyt; go drop proc fantastik STORED PROCEDURE OLUŞTURMA KILAVUZU: Stored Procedure oluştururken dikkat edeceğimiz yapılar; Tüm Stored Procedure'ların, aynı bağlantı ayarlarını kullanması gerekir. Bunun için SQL Server; stored procedure oluştururken veya değiştirirken iki ayarı kaydeder. Bunlar: SET OUOTEDJDENTIFIER ve SET ANSI_NULLS. Bunların seçenekleri ON ve OFF'dur. ANSI_NULLS; OFF olursa boş olan değerler NULL olarak döner. ON olursa; hiçbir şey yazmaz. SET OUOTEDJDENTIFIER; String değerleri içinde kullanılan tırnak işareti durumunu belirtir. Bu değer ON olduğu zaman tanımlamalar; çift tırnak kullanımı içine alınır ve bilgiler için mutlaka tek tırnak kullanılması gerekir. Eğer OFF olursa; tanımlayıcılarda tırnak kullanılmaz ve Transact-SQL içinden gelen tüm kurallara uyulması gerekir. Bu yapıyı bir örnek ile ifade edersek, sanırım daha iyi anlaşılacaktır. UYGULAMA: 1) Aşağıdaki kodu yazdığımızda OFF olduğundan, çalışmayacaktır. Hata mesajı ile karşılaşacağız. Çünkü tablo adını ve sütun adlarını çift tırnak içinde yazdık. Set QUOTED_IDENTIFIER OFF GO CREATE TABLE “personel2” (“sicilno” int IDENTITY,”maas” int) GO Hata mesajı;
  • 11. 2) Aşağıdaki yazılımda değeri ON yaptığımız için çalışacaktır. Dikkat edelim, ifadelerde çift tırnak kullanıyoruz Set QUOTED_IDENTIFIER OFF GO CREATE TABLE “personel2” (“sicilno” int IDENTITY,”maas” int) GO DROP TABLE “personel2” SET QUOTED_IDENTIFIER OFF 3) Aşağıda ise bu kurallar string değerler içinde kullanılmıştır. set quoted_identifier on go create table "personel2"("sicilno" int identity, "maas" int) go select "sicilno","maas" from "personel2" order by "maas" go drop table "personel2" set quoted_identifier off
  • 12. 4) Kod çalıştığında sonuç, aşağıdaki gibi olur. 5) Bu ayarları veri tabanı için ON veya OFF pozisyonuna; grafiksel olarak getirmek için, veri tabanı üzerinde sağ tuşa basarak, Properties seçeneğine tıklanır. Gelen iletişim kutusundan Options sayfasına geçilir. Burada bulunan ANSI NULL Default ve Quoted identifiers Enabled seçenekleri kullanılır. Açmak için True, kapatmak için ise False değerleri seçilir.
  • 13. Diğer seçenekler; stored procedure tarafından kaydedilemez. Örneğin; SET ARITHABORT, SET ANSI_WARNING, SET ANSI_PADDING. *** OBJECTPROPERTY sistem fonksiyonu kullanılarak, seçeneklerin durumunun ne olduğu öğrenilebilir. Döndürdüğü değer "1" olduğu zaman açık anlamındadır. Aşağıdaki örnek kod, bir nesnenin adını ve tipini kontrol ederek, ne olduğunu söylemektedir. if exists (select * from dbo.sysobjects where id=object_id('[supermanler]') and objectproperty(id,'isprocedure') = 1) print 'bu bir stored procedure' Veya if OBJECTPROPERTY(object_id('supermanler'),N'isprocedure')=1 print 'bu bir stored procedure' Eğer koşul doğru ise 'Bu bir stored procedure' ifadesi çıkar * EXECUTE ifadesi ile bir stored procedure'ü çalıştırmak yerine, sp_executesql sistem stored procedure'ü ile çalıştırmak, performans açısından daha doğru bir seçimdir. * Stored Procedure ile ilgili bilgiler syscomments sitem tablosunda tutulur. Bu tablo içindeki bilgileri silmemiz mümkün değildir. Bu görünüme sp_helptext sistem stored procedure ile ulaşabiliriz. Ancak stored procedure içine yazdığınız bilgilerin; başkaları tarafından görünmesini istemiyorsanız, bunun için mutlaka stored procedure oluştururken; WITH ENCRYPTION seçeneğini kullanmanız gerekir. create proc fantastiklOOl WITH ENCRYPT10M As select * from müşteriler I Bu seçeneği kullanarak oluşturulan stored procedure'ün üzerinde sağ tuşa basılınca Modify seçeneğinin pasif olduğu görünür.
  • 14. UYGULAMA: 1) Aşağıdaki örnek ile ilk önce, fantastik isimli bir stored procedure varsa onu siliyoruz. Daha sonra tırnak tanımlamasını kapatıp, boş değer seçeneğini açarak; fantastik isimli bir stored procedure oluşturuyoruz. Bunun özelliği; müşteriler tablosundaki ilk 5 kaydı seçmesi ve musterino ya göre büyükten- küçüğe doğru sıralamasıdır. Son olarak, oluşturduğumuz fantastik isimli stored procedure'ü, exec ifadesi ile çalıştırıyoruz. 2) çalıştırmak için aşağıdaki ifadeyi kullanalım USE cuneyt; GO IF EXISTS (SELECT * FROM dbo .sysobjects WHERE id = object_id('fantastik') and OBJECTPROPERTY(id,'IsFrocedure') = 1) DROP PROCEDURE [dbo].[fantastik] GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO CREATE PROCEDURE [fantastik] AS SELECT TOP 5 * FROM musteri ORDER BY musterino desc
  • 15. 3) Bir stored procedure içinde yazılı kodları görmek için; sp_helptext sistem stored procedure'ü kullanılır. Aşağıdaki yazılım ile "fantastik" stored procedure'ün yazılımı hakkında, bilgi sahibi oluyoruz. 4) Çalıştırılınca çıktısı, aşağıdaki şekildeki gibi olacaktır. 5) Oluşturduğumuz "fantastik" isimli stored procedure'ün ID'sini öğrenmek için, aşağıda*ki kodu yazmamız gerekir. 6) Ççalıştırınca çıktısı, aşağıdaki gibi bir sayısal değer olacaktır 7) ANSI NULL bağlantı ayarlarının açık olup- olmadığını öğrenmek için aşağıdaki kodu yazıyoruz. Eğer sonuç "1" çıkarsa, açıktır. Buraya yazılan sayısal değer, bir önceki adımda bulduğumuz değerdir. Yani, "fantastik" stored procedure'ünün kimlik numarasıdır. 8) Çalıştırınca "1" çıkıyorsa açık(ON), "0" çıkıyorsa kapalıdır(OFF). Biz uygulamamızın ilk adımında; SET ANSI_NULLS ON ifadesini kullandığımız için, sonucun "1" çıkması gerekir. SELECT OBJECT_ID(fantastik’)
  • 16. 9) Aşağıdaki ifade çift tırnak durumunu kontrol eder Select objectproperty(2133582639,’ExecIsQuotedIdentOn’) 10) Aşağıdaki yazılımda tırnak özelliği kapatıldığı için, çift tırnak ifadesi içinde ayıraç işareti olarak, tek tırnak kullanabildik. Yani, Türkiye'nin ifadesini yazabildik. SET QUOTED_IDENTIFIER OFF GO ÜSE cuneyt CREATE TABLE Test i sicilno int, textdurumu varchar (50) i GO INSERT INTO Test VALUES (1,"Türkiye'nin Başkenti Ankara'dır") GO SELECT * FROM Test 10) Çalıştırdığımızda test tablosunun içine kaydı, aşağıdaki şekilde ilave edecektir. 11) Ancak SET OUOTEDIDENTIFIER ON yaparak çalıştırdığımızda, bu işlemin gerçekleşmediğini göreceğiz. Yukarıdaki kodun aynısını yazarak deneyiniz. Ancak ilk önce test tablosunu silmeyi unutmayınız. Bunun sonucunda, işlemin gerçekleşmeyeceğini bildiren aşağıdaki mesaj ile karşılaşacaksınız ve tablonun içine hiçbir kaydın eklenmeyeceğini göreceksiniz.
  • 17. 12) Şimdi bir stored procedure ile son olarak, tırnak olayını kullanalım. SET QUOTED_IDENTIFIER OFF --Oluşturumadan önce off yapıyoruz ki tek tırnak olayına uygun olsun. GO USE cuneyt Go create procedure test3 as INSERT INTO Test VALUES (2,"Türkiye'nin Başkenti Ankara'dir") GO 14) Çalıştırmak için, aşağıdaki kodu uyguluyoruz. INSERT INTO Test2 EXEC test3 15) "Test" isimli tabloyu açarak, verilerin içine kaydedildiğini kontrol ediyoruz.
  • 18. STORED PROCEDURE İÇİNDE PARAMETRE KULLANIMI: Stored Procedure'leri daha fonksiyonel olarak kullanmak için, parametreli olarak tasarlamak gerekir. Örneğin; kitap adına göre sorgulama yapmayı planlıyoruz, eğer direkt kitap adını sorgulama içine yazarsak, başka bir kitap adı için her seferinde değişiklik yapmamız gerekir. İşte bu durumda; kitap adını parametre olarak tanımlarsak, sorgulamayı dinamik olarak kullanabiliriz. Output ve Input olmak üzere, iki adet parametre vardır. Ancak SQL Server 2012 ile beraber bir üçüncü parametre tipi eklenmiştir ve bunun adı da Table- Valued' dir. INPUT PARAMETRE: Input türü parametreler kullanarak; SQL Server içine bilgilerin geçişini sağlarız. CREATE PROC ifadesi ile kullanılan bu yazılım, bir veya daha fazla olabilir. Kullanım biçimi: ©parametre adı veritipi[=default] Dikkat edilecek noktalar; * Tüm giriş türlü parametreler, stored procedure başında uygun olup-olmadığı kontrol edilir. * Eğer input parametre tanımlarken bir default değer verilmiş ise, o zaman özel bir değer atamaya gerek yoktur. Parametreler mutlaka bir değer içermeli veya NULL tanımlaması yapılmalıdır. Bunun dışındaki durumlarda hata oluşur. * Bir stored procedure içinde en fazla, 2100 adet parametre tanımlanabilir. * Lokal değişkenlerin sayısı ise hafıza ile sınırlıdır. - * Parametre adları, sadece o stored procedure için geçerlidir. Aynı isim, başka bir stored procedure için de kullanılabilir. * Parametre bilgileri, syscolumns sistem tablosunda tutulur. Oluşturulan parametreli stored procedure'lerin çalıştırılması için; EXECUTE stored procedure_adı ifadesinden sonra @parametre_adı=verilecek_değer ifadesi yazılarak, parametrelere değer atanır. Kullanım biçimi; [EXECUTE] procedure_adı [@parametre_adı=atanacak_değer[OUTPUT][DEFAULT] [WITH RECOMPLIE] Ayrıca direkt olarak execute ve stored procedure adından sonra araya, virgül koyularak parametreler girilebilir. Boş geçilecek değerlere Null yazılmalıdır.
  • 19. UYGULAMA: 1) "Satis" isimli tablomuzun tasarım kısmına geçerek en üst satıra, "kayitno" isimli yeni bir sütun ekleyelim ve aşağıdaki Columns kısmından İdentity özelliğini Yes yapalım. Son olarak kayitno sütunu üzerinde sağ tuşa basarak, Set Primary Key seçeneğine tıklayıp, bu Constraint'i uygulayalım. Gerek SQL Server içinde, gerekse diğer kullanılan programlarda sorunsuz olarak Insert, Update ve Delete ifadelerini çalıştırmak için tabloda, bir Primary Key olması tavsiye edilir. 2) Kayıtların son görünümü, aşağıdaki gibi olmalıdır. 3) "Satis" tablosuna yeni kayıt girişi yapacak Stored Procedure'ü aşağıdaki gibi tasarlayalım. Burada ilk değer olan kayitno; identity özelliğine sahip olduğu için buna bir değer atayamayacağız, kendisi otomatik olarak oluşturacak. Ayrıca bize sadece yeni eklenen kayıdı döndürecek. Bunun için bir sistem fonksiyonu olan @@IDENTITY ifadesinden yararlanıyoruz. Bu fonksiyon yeni eklenen kayıdın numarasını tutar. Tabii bunu tutması için o sütunun Identitiy özelliğinin aktif olması gerekir. Biz kayitno sütununda bu özelliği aktif hale getirmiştik.
  • 20. use cuneyt; go CREATE procedure yenikayit_satis ( @musterino int, @filmad nvarchar(50), @fiyat int, @alistarih datetime, @getiristarih datetime) AS INSERT INTO satiss(musterino,filmad,fiyat,alistarih,getiristarih) values (@musterino,@filmad,@fiyat,@alistarih,@getiristarih); select kayitno,musterino,filmad,fiyat,alistarih,getiristarih from satiss where(kayitno=@@IDENTITY) go 4) Bu Stored Procedure'ü çalıştırmak için; exec komutu ile berabe* parametreleri de belirtmemiz gerekir. set dateformat dmy go exec yenikayit_satis @musterino=101, @filmad='misterno', @fiyat=5, @alistarih='14/01/2011', @getiristarih='22/01/11' 5) Bir üstteki yazılım yerine, aşağıdaki şekilde de yazabiliriz. Burada kullandığımız DATEFORMAT fonksiyonu ile girilecek tarihi gün-ay-yı| biçimine getiriyoruz. Aşağıdaki yazılımda parametre ismi belirtilmediği için stored procedure içinde bulunan sıraya göre yazılmalıdır. Oysa bir önceki adımda böyle bir zorunluluk yoktur. set dateformat dmy go exec yenikayit_satis 102,'misterno',5.5,'22/01/2011','25/02/2011' 6) Eğer herhangi bir sütun yerine, hiçbir şey yazmadan geçmek istiyorsak; aşağıdaki şekilde yazmamız gerekir. Fakat sütunun tasarım kısmında boş geçilebilir(Allow null) izninin olması gerekir.
  • 21. Not: ADO .NET için değişken adı ile input parametre değerlerinin avnı olması yararlıdır. 7) Bu işlemler sonucu satis tablomuzun son görüntüsü, aşağıdaki şekilde olacaktır. 8) Boş olan ve olmayan kayıtları aynı anda sorgulamak istersek, aşağıdaki şekilde yazmamız gerekir. İlk önce ansi_nulls özelliğini on yaparak çalıştıracağız. Aşağıda where ifadesinden sonraki yazılım, hem on durumunda hem de off durumunda çalışır. 9) Aşağıdaki ifade ise sadece, ansi_nulls özelliği off durumunda iken çalışır. set ansi_nulls off select * f rom sat is where alistarih=Null. select : " frorn satis where alistarih=Null 10) Şimdi var olan bir kayıt üzerinde değişiklik yapan; UPDATE ifadesini kullanalım CREATE PROCEDURE degistir_satis ( @musterine int, (@filmad nvarchar50) , @fiyat int, @alistarih datetime, @getiristarih datetime, @Original__kayitno int ) AS SET MOCOUNT OFF; UPDATE satis SET musterino = @musterino, filmad = @filmad, fiyat = @fiyat, alistarih = @alistarih,
  • 22. getiristarih = @getiristarih WHERE (kayitno = @Original_kayitno) 11) Aşağıdaki yazılımı kullanarak, ilk kayıdın müşteri numarasını 102, kitabın fiyatını 66 ve adını benten olarak değiştireceğiz. exec degistir_satis @musterino=102, @filmad= 'benten ', @fiyat=66,@alistarih=’17/10/2010', @getiristarih=' 22/10/2010', @Original_kayitno=1) 12) Çalıştırdığımızda ilk kayıt; şekildeki gibi değişikliğe uğrayacaktır. 13) Şimdi var olan bir kayıdı silmek için Delete ifadesini kullanalım. Aşağıdaki ifade, silmek için gerekli kodu oluşturuyor CREATE PROCEDURE satis_sil ( @Original_kayitno int ) AS DELETE FROM satis WHERE (kayitno = @Original_kayitno) 14) Aşağıdaki yazılım ile 11 numaralı kayıdı siliyoruz. exec satis_sil @Original_kayitno-=11
  • 23. UYGULAMA: 1) Aşağıdaki yazılım müşteriler ve satis tablosunu birleştirerek verdiğimiz film adına göre kayıtları göstermektedir. create proc muster_satis2 @fad nvarchar(20) as if @fad is null begin raiserror('bos deger olamaz',14,1) return end select sati.musterino, sati.filmad, musteri.mad, sati.alistarih, datename(mm,alistarih) as aylar from sati inner join musteri on sati.musterino=musteri.musterino where sati.filmad=@fad go 2) Çalıştırmak için aşağıdaki kodu yazdığımızda, tablomuzdaki kayıtlara göre aşağıdaki kaydı görebiliriz. 3) Boş bir film yazıldığında ise şekildeki gibi hata mesajı gelir.
  • 24. OUTPUT PARAMETER: Bir Stored Procedure'ü çağırdığımız zaman, içinde bulunan değeri döndürebilir.Bunun için OUTPUT ifadesi kullanılır. * Eğer OUTPUT değişkeni bir değer almaz ise, yine de Stored Procedure çalışır, ama değer fırlatmaz. * Text ve image dışında herhangi bir veri tipi olabilir. * Çalıştırırken yine exec komutu kullanılır. 1) Aşağıdaki Stored Procedure, dışarıdan gelen iki değeri hesaplayarak @sonuc isimli değişkene atıyor. @sonuc değişkeni Output ile tanımlandığı için bu, dışarıya kullanılmak için gönderilebilir. create proc carp @a int, @b int, @sonuc int output* as set @sonuc=@a*@b go 2) Çalıştırmak için gerekli yazılım, aşağıdaki gibi olmalıdır. declare @c int execute carp @a=12, @b=5, @sonuc=@c output select 'sonuc:',@c
  • 25. 3) Çalıştırıldığı zaman çıktısı, aşağıdaki gibi olacaktır. TABLE-VALUED PARAMETER: SQL Server 2012 ile birlikte gelen yeni bir parametre tipi vardır. Bu Table-valued parameter olarak adlandırılır. Kullanıcı tanımlı tablo tipi i|e deklare edilir. Böylelikle geçici tablo veya birçok parametre kullanmaya gerek kalmadan, birçok satır kullanılabilir. UYGULAMA: 1) "ana" isimli tabloyu şekildeki gibi tasarlayarak, içine iki kayıt girelim.
  • 26. 2) Aşağıdaki ifadeleri yazarak çalıştıralım. USE cuneyt; GO CREATE TYPE a1 AS TABLE ( ad VARCHAR(50) ,fiyat INT ); GO Create PROCEDURE as1 @TVP al READONLY AS SET NOCOUNT ON INSERT INTO ana ([ad] ,[fiyat] ,[durum] ,[tarih]) SELECT *, 0, GETDATE() FROM @TVP; GO 3) Test için aşağıdaki ifadeleri yazarak "ana" tabloyu kontrol edelim. DECLARE @t1 as a1; insert into @t1(ad,fiyat) select[ad],0.00 from ana exec as1 @t1 go STORED PROCEDURE'LERİN YENİDEN DERLENMESİ: Stored Procedure normalde bir kez çalıştıktan sonra kendini; Cache içine yerleştirerek, daha hızlı çalışmayı sağlar. Ancak aşağıdaki durumlarda Stored Procedure' ün yeniden derlenmesi gerekir. * Parametreler; Stored Procedure içine geçtikten sonra, çok geniş bir değer döndürürlerse.
  • 27. * Stored Procedure için yararlı olabilecek yeni bir index, tabloya eklenirse. * Parametre değerleri başka tipe dönüşüyorsa. Yeniden derlemek için, WITH RECOMPILE ifadesi kullanılır. Çalıştırırken Exec procedure_adı With recompile veya Exec sp_recomplie procedure__adı ifadeleri kullanılabilir. Eğer bir Stored Procedure'ün, Cache içinde tutulmasını değil de, her seferinde yeniden derlenmesini istiyorsak, o zaman With Recompile komutunu kullanırız. Aşağıdaki ifade bunu sağlar. use cuneyt go create proc yeniden @a nvarchar(10) with recompile as select COUNT(*) from sati where filmad=@a go Çalıştırmak için aşağıdaki kodu yazalım ve sonucu gözlemleyelim. Eğer tablolarımız aynı ise "2" değerinin çıkması gerekir. Exec yeniden ' superman' Cache içinde bulunan tüm Stored Procedure planlamalarını silmek için, aşağıdaki ifade kullanılır. Dbcc freeproccache HATA MESAJLARI: Stored Procedure'leri daha etkili kullanmak için; bünyesinde hata mesajları tanımlanarak bir hata durumunda, kullanıcı bilgilendirilebilir. Bu sadece hata durumlarında değil, aynı zamanda olumlu durumlarda da tercih edilebilir.
  • 28. Burada döndürülecek değer; Return ifadesi ile belirlenebilir. Eğer Return değeri "0" ise işlem başarılı, "0" ile "14" arasında ise aktif kullanılan, "15" ile "99" arası ise gelecekte kullanılacak değerlerdir. Eğer kullanıcı tanımlı Return değeri desteklenmiyorsa SQL Server, kendisininkini kullanır. UYGULAMA: 1) Aşağıdaki örnek, sistem fonksiyonu olan @@rowcount ile satır sayısını döndürmektedir. use cuneyt go create proc kactane @f char(10) as select * from sati where filmad=@f return (@@rowcount) go 2) Çalıştırmak için, aşağıdaki kodu yazmak yeterlidir. declare @x int exec @x=kactane @f='superman' print @x Çıktısı, şekildeki gibi olacaktır. 3) Özel hata mesajı oluşturmak için sp_addmessage system stored procedure'ü kullanılır. Böylelikle master tablosu içinde bulunan sysmessages; sistem tablosu içine yazılır.
  • 29. Ayrıca hata durumu, Windows 2003- 2012 Application log yapısında bulunur. Aşağıdaki ifade bu yapıya ait bir örnektir. use master exec sp_addmessage @msgnum=50010, @severity=10, @msgtext='yapma böyle hatalar', @with_log='true' 4) Burada kullanılan parametrelerden msgnum ile kayıt numarasını, severity parametresi ile hatanın türünü ve önemini belirtiyoruz. Bu, çeşitli düzeylerden oluşuyor. Eğer "10" değerini verirsek bu; kullanıcının yanlış bilgi girişi yaptığı bilgisini, 11- 16 arası düzeyde ise kullanıcının doğru bilgi girmesini, 17-25 arası ise yazılım ve donanım ile ilgili hataları gösterir. msgtextı çıkacak mesajı belirler. Hem Windows hem de SQL log'larına yazılması istenirse, with_log seçeneğinin true yapılması gerekir. Master veri tabanı içindeki sysmessages tablosunu sorgulamak için aşağıdaki ifadeyi yazarak çalıştırdığımızda, tabloda kendi mesajımızın eklenmiş olduğunu görebiliriz. 5) Mevcut bir mesajı değiştirmek için, replace özelliği aşağıdaki gibi kullanılır. exec sp_addmessage @msgnum=50010, @severity=10, @msgtext='dikkat hatası var', @with_log='true', @replace='replace'
  • 30. Not: Kullanıcı tanımlı mesaj oluşturmak veya bunları değiştirmek için kullanılacak numaraların, 50000'den büyük olması gerekir. Bu yapılarda yaygın olarak kullanılan diğer bir sistem fonksiyonu @@error' dur. Bu fonksiyon "0" değerini alırsa hata yok, aksi durumda hata var anlamındadır. Diğer bir hata mesajı yapılandırma Raiserror ifadesi ile olur. Kullanıcı tanımlı hata mesajları kullanılabileceği gibi, direkt bir açıklama da yazılabilir. Bundan sonra mutlaka bir severity düzeyi ve mesaj durumu sayısal olarak belirtilmelidir. Mesaj durumu 1-127 arası bir değer alabilir. Bu, destek mühendisleri için bir bilgilendirme olarak kullanılabilir. "-1" yazılırsa da bu 1 olarak işlem görür yani, varsayılan ayardır. Eğer mesajın Event viewer içindeki Application log içine yazılmasını istersek, sonuna With log ifadesi koyabiliriz. Gerçi 0-17 arası değer hata kodunda tanımlanmış ise otomatik olarak yazar, ancak özel hatalar olan 17 sonrası için kullanmamız gerekir. Aşağıda, daha önce oluşturduğumuz 50010 numaralı mesajın, Raiserror ile kullanılması gösterilmiştir. raiserror(50010,10,1)with log raiserror(50010,16,1) raiserror(50010,25,1)with log raiserror('zor dostum zor',15,1) with log raiserror(50010,15,1) Event viewer seçeneğini Administrative Tools içinden açtığımızda bu hata ve bilgi mesajlarının yazıldığı görülecektir. 13 numaraya kadar olanlar Information şeklinde yazılırken, 14 Warning, diğerleri ise Error olarak yazılır. Administrative Tools içinden Event Viewer seçeneğine tıklanıp, Application Log kısmı
  • 31. seçildiğinde SQL Server tarafından fırlatılan bilgi, uyarı ve hata mesajları görüntülenecektir. UYGULAMA: 1) Daha önce oluşturduğumuz "müşteriler" tablosunun tasarım kısmına geçerek, "musterino" sütununa Primary Key koyalım. 2) Bu tablomuzdaki son kayıt durumu, şekildeki gibi olsun. 3) Aşağıdaki hata mesajını oluşturalım. exec sp_addmessage @msgnum=50025, @severity=16, @msgtext='boyle bir musteri yok', @with_log='true' 4) Yukarıdaki kodu çalıştırdıktan sonra, Master veri tabanı içinde bulunan;
  • 32. sysmessages sistem tablosunu sorgulayarak mesajımızın burada oluştuğunu gözlemleyelim. 5) Aşağıdaki Stored Procedure'ü oluşturalım. Bu stored procedure, girilen müşteri numarası ve yeni telefon numarasına göre, var olan müşterinin telefonunu değiştirecektir. Eğer müşteri numarası boş bırakılırsa lütfen müşteri numarasını giriniz mesajı, müşterinin numarası yanlış girilirse böyle bir müşteri yok mesajını verecektir. Her şey doğru ise başarı ile değişmiştir ifadesini gösterecektir. create procedure musteri_telefon__degisiklik @musterino int=null, @mtel varchar (15) =null as if @musterino is null begin print 'Lütfen Müşteri numarası giriniz' return end if not exists (select * from musteri where musterino=@musterino) begin raiserror(50025,16,1)--Böyle bir müşteri yok return end begin transaction update musteri set mtel=@mtel where musterino=@musterino select convert (varchar (25),@musterino) + ' noiu müşterinin telefonu' + @mtel+ 'alarak babari ile degismistir ' commit transaction 6) Aşağıdaki şekillerde stored procedure'ü çalıştırarak, çıkan sonuçları Gözlemleyelim. İlk ikisinde işlem gerçekleşmeyecek, üçüncüde ise başarı jle gerçekleşerek; 101 numaralı müşterinin telefonunu değiştirecektir. exec musteri_telefon__degisiklik @musterino=null, @mtel='05367370566'
  • 33. 7) Gerçekten de müşteriler tablosunu açtığımızda, bu değişikliğin olduğunu göreceğiz. Bu bölümde son iki konuda anlattığımız yapılar hakkında uygulamalar geliştirerek, bilgilerin daha iyi oturmasını sağlayacağız. Bunları mutlaka uygulayınız. VİEW ve STORED PROCEDURE UYGULAMALARI UYGULAMA: SENARYO: cuneyt veri tabanı içinde satış tablosunu temel alarak bir Stored Procedure'ü aşağıdaki gibi geliştiriyorsun. Buradaki amaç, film adlarını verince, yıl sonu satış raporlarını göstermek. CREATE PROCEDURE satisrapor @filmad varchar(8), @toplamciro money OutPUT AS SELECT @toplamciro = SUM(fiyat) FROM satis WHERE filmad=@filmad IF @toplamciro > 0 RETURN(1) RETURN(0) 1) Yukarıdaki kod ile dışarıdan girilen film adını @filmad isimli değişken yakalıyor, satis tablosundan bu bilgiye uyan fiyat bilgisini @toplamciro isimli Output değişkene atıyor. Eğer bunun sonucunda bir toplam değeri oluşmuş ise 1, sıfır olarak kalmış ise 0 değerini döndürüyor. Sıfır olarak kalınca "demek ki öyle bir film yok" anlamına geliyor. 2) Sen bu Stored Procedure'ü çalıştırdığın zaman, eğer verdiğin film adı veri tabanında bulunuyorsa; bu filmin yılsonu toplam cirosunu göstersin. Ancak bulunmuyorsa yani 0 değerini döndürüyorsa "Film Bulunamadı" mesajını çıkarmasını istiyorsun.
  • 34. Bunun için çalıştırma yazılımını nasıl yaparsın? 3) ÇÖZÜM: Burada dönen değerleri bir lokal değişkene aktararak bu lokal değişkeni sorgulamak, en doğru çalıştırma şekli olacaktır. Bu bilgiler göz önüne alınarak, yazılım aşağıdaki gibi olmalıdır. DECLARE @gelen int DECLARE @sonuc money EXEC @gelen=satisrapor '2012', @sonuc output if @gelen=0 print 'kitap bulunamadı' else begin print 'bu kitabın yılsonu satisi : ' print convert(varchar(15),@sonuc) + 'yil' end go Yukarıdaki yazılımı yorumlayacak olursak; * @gelen ve @sonuc isimli iki lokal değişken tanımlıyoruz. * Stored procedure'ü çalıştırırken 2012 isimli filmi sorguluyoruz ve fırlatacak değeri sonuna koyduğumuz @sonuc değişkenine atarken, fonksiyonun döndüreceği değeri yani 0 veya 11 @gelen isimli değişkene atıyoruz. * Eğer @gelen sıfıra eşitse yani 0 ise "Film Bulunamadı" mesajını çıkartırken, aksi durumda ön açıklama bilgisi ile birlikte ekrana yansıtıyoruz. 4) Kodu çalıştırdığımızda görüntü, şekildeki gibi olacaktır. UYGULAMA: 1)SENARYO: Online kitap satışı yapmak için bir yapı tasarlamak istiyorsun. Müşteriler kitap siparişini, Web sitesini kullanarak yapacaklar. Verilen siparişler yüksel veri tabanı içindeki kitapsiparis isimli tabloya yazılacak. Ancak sen bu gelen bilgilerden bazılarını raporlar isimli bir tabloya aktaracaksın ve bu tabloyu da internet ortamında yayımlayacaksın. Bunun için gerekli Stored Procedure yapısını nasıl oluşturursun. 2)ÇÖZÜM: İlk olarak bu iki tabloyu aşağıdaki şekilde tasarlarım.
  • 35. Bu tablodan sadece kitapad ve adet bilgilerinin kopyalanacağı diğer tablo tasarımını ise şekildeki gibi yapalım. İçlerine hiçbir kayıt girmeyelim. 3)Tablolara veri girişi sağlayacak, bir Stored Procedure hazırlayalım. create procedure siparis2 @musterino int, @musteriad varchar (40), @kitapad varchar(40), @fiyat money, @musteritel varchar (40), @adet int as insert into kitapsiparis values (@musterino,@musteriad,@kitapad,@fiyat,@musteritel,@adet) insert into raporlar values (@kitapad,@fiyat) 4)Ardından aşağıdaki şekilde çalıştıralım. exec siparis 104,'yuksel inan','c# 2010',40,'3333333',5 exec siparis 107,'yuksel inan','ASP.NET 2010',45,'2222222',12 5)Tabloları açarak, içine kayıtların yazıldığını gözlemleyelim. UYGULAMA: 1) SENARYO: Şirketin veri tabanı yöneticisisin. Veri tabanı içinde "Satışlar" isimli bir tablo var ve yaklaşık 2 milyon satıra sahip. Bu tablo, şirket içinde bulunan tüm
  • 36. bölümlere ait satış bilgilerini içermektedir. Her bölüm bu tablo içinde bulunan BölümNo sütununda tanımlanmıştır. Uyguladığın sorgulamalarda bir bölümü istemene karşın, tüm bilgileri tarıyor. Bu sorguların l/O performansını arttırmak istiyorsun fakat, uygulamaların tabloyu açışında bir değişiklik yapmak daha doğrusu; uygulamaların etkilenmesini istemiyorsun. Ne yapman gerekir? 2)ÇÖZÜM: Bu kadar kayıt varsa, bu tabloyu parçalara ayırmak gerekir. Bunun için aşağıdaki işlemleri yaparım. * Her bir bölüm için, yeni bir tablo oluştururum. * Her bölüme ait satış bilgilerini Satışlar tablosundan, kendilerine ait olan tablonun içine taşırım. * Yeni tabloların BölümNo sütununa, bir CHECK Constraint'i koyarım. * Yeni tablolarla ilgili bir View oluştururum. 3) SENARYO: Bir veri tabanı yöneticisisin. Oturup, temizlik yapmaya karar verdin© ve SQL Server içinde kullanılmayan eski nesneleri silmek istiyorsun. Eski bir View gördün adı "1997" ve silmeye çalıştın ancak, silemedin. Araştırmaların sonucu şu bilgileri edindin; *** Bir Clustered lndex var. *** Bu View üzerinde gerekli hakkın var. *** View içinde WITH SCHEMABINDING kullanılmış. *** View oluşumunda bir in-line fonksiyon kullanılmış. *** INSTEAD OF Trigger tanımlanmış, 4) Ne yapman gerekir? 5) ÇÖZÜM: Burada sıralanan maddelerden hiçbiri View silinmesini engellemez. Demek ki fonksiyon içinde WITH SCHEMABINDING var. Onun için bu fonksiyonu adam etmek gerekir. Yani, içindeki WITH SCHEMABINDING silinmesi gerekir. 6)Bir View oluşturulurken WITH SCHEMABINDING aşağıdaki şekilde View ile ilişkilendirilir. create view satis8 with schemabinding as select filmad,fiyat from dbo.satis where filmad = 'superman'
  • 37. 7) SENARYO: Bir oyuncak üreticisinin veri tabanı yöneticisisin. Şirkette çalışanlar idareci, yönetici ve çalışan olarak üç kategoriye ayrılmış. Şirketin intranet Web ana sayfasında bu üç pozisyona ait haberler tasarlanmış durumdadır. Bir kullanıcı Log On olunca, kendi pozisyonuna ait haberleri izleyebiliyor. Şirket haberleri "haberler" isimli tablo içinde tutuluyor. Kullanıcılar bu tablo içindeki bilgileri sadece görebilecek, fakat değişiklik yapamayacak ayrıca, kendi bölümüne ait verilere ulaşacak. Bunun için ne yapman gerekir? 8)ÇÖZÜM: Bu yapı için en uygun Stored Procedure oluşturmaktır. Tablo içinde bulunan kategori bilgisine bir parametre gönderilerek ve SELECT ifadesi kullanılarak sadece kendine ait bilgilere ulaşması sağlanır. UYGULAMA: 1) SENARYO: Sen danışmanlık hizmeti sağlayan bir şirketin veri tabanı danışmanısın.. Bu şirket elemanlarına ait bilgiler, aşağıdaki şekilde oluşturulmuş "personelim" isimli tabloda tutuyor. create table personeller ( perno int not null, pertip char (1) not null, perad varchar(50), adres varchar(50) null, telefon varchar(20) null, constraint PK_perno primary key (perno)) 2) Bu tabloda bulunan pertip isimli sütunda çalışanların vasıfları belirleniyor. Bunlar yönetici, danışman, sekreter gibi bilgiler içeriyor. En üst yönetici olan yöneticilere; danışman grubunda bulunan elemanlar dışında bu tablodaki kayıtlar üzerinde değişiklik yapma, yeni kayıt ekleme ve silme yetkisi vermek istiyorsun nasıl yaparsın? 3) ÇÖZÜM: Aşağıdaki şekilde kayıtları gireriz. Burada 1 numara yönetici, 2 numara sekreter, 3 numara danışman kategorisinde çalışanları göstermektedir.
  • 38. 4) Aşağıdaki şekilde WITH CHECK OPTION parametresi ile oluşturduğumuz View'da, 3 no'lu kayıtlar için yapılandırma yapılmasını engelliyoruz. create PROCEDURE StokGuncel @stokno int, @fiyat money AS BEGIN DECLARE @hatano int, @say int, @Msg varchar (50) UPDATE stoklar SET fiyat=@fiyat WHERE stokno=@stokno AND fiyat<>@fiyat SELECT @say=@@ROWCOUNT If @say = 0 RAISERROR ('Hata kodu %d , Güncellenemeyen Stok No %d.', 10, 1, @say, @stokno) WITH log ELSE SELECT 'Stok numarası' + STR (@stokno) + ' olanın yeni fiyatı ' + STR (@fiyat) + '.' END 5) Elemanlar isimli View'ı açıp, pertip kısmına 3 yazarak yeni bir kayıt girmeye kalktığımızda, izin vermeyecektir. Ancak diğer pertip bilgilerini kullanarak, kayıt girebiliriz. Bu kural; değişiklik ve silme için de geçerli olacaktır. UYGULAMA: 1)SENARYO: Bir firmanın veri tabanı geliştiricisisin. Eski Stok fiyatları güncellenirken bir hata meydana geldiğinde, bu hatanın da günlüğünün(log) tutulması ve Client uygulamasına hata mesajının dönmesi gerekiyor. Bu yapıyı sağlayacak planlamayı nasıl yaparsın?
  • 39. 1) ÇÖZÜM: Stoklar tablosunu şekildeki gibi, tasarlayalım. İçine şekildeki kayıtları girelim. 2) Esas sorumuzun cevabını oluşturan Stored Procedure'ü aşağıdaki gibi oluşturalım. Bu Stored Procedure'ü analiz edecek olursak; * Dışarıdan girilen parametreler @stokno ve @fiyat değişkenleri tarafından yakalanıyor. * Stoklar tablosunu, bu iki değere bakarak güncellemeye çalışıyor. * Eğer bir hata olursa RAISERROR ile bunu hem kullanıcıya, hem de Event Viewer içine fırlatıyoruz. *** Eğer işlem başarı ile gerçekleşirse, bu bilgiyi sunuyoruz. 3) Test etmek için, aşağıdaki kodu yazalım;
  • 40. 4) Kodu çalıştırdığımızda aşağıdaki mesaj ile karşılaşırız. Aynı zamanda tablo içine baktığımızda, değerin değiştiğini görebiliriz.