Upload
oktay-goekgoel
View
218
Download
4
Embed Size (px)
Citation preview
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
Programmability\Stored 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.