40
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.

9.hafta cüneyt tomruk

Embed Size (px)

Citation preview

Page 1: 9.hafta cüneyt tomruk

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.

Page 2: 9.hafta cüneyt tomruk

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.

Page 3: 9.hafta cüneyt tomruk

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.

Page 4: 9.hafta cüneyt tomruk

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.

Page 5: 9.hafta cüneyt tomruk

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.

Page 6: 9.hafta cüneyt tomruk

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

Page 7: 9.hafta cüneyt tomruk

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

Page 8: 9.hafta cüneyt tomruk

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.

Page 9: 9.hafta cüneyt tomruk

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

Page 10: 9.hafta cüneyt tomruk

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ı;

Page 11: 9.hafta cüneyt tomruk

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

Page 12: 9.hafta cüneyt tomruk

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.

Page 13: 9.hafta cüneyt tomruk

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.

Page 14: 9.hafta cüneyt tomruk

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

Page 15: 9.hafta cüneyt tomruk

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’)

Page 16: 9.hafta cüneyt tomruk

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.

Page 17: 9.hafta cüneyt tomruk

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.

Page 18: 9.hafta cüneyt tomruk

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.

Page 19: 9.hafta cüneyt tomruk

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.

Page 20: 9.hafta cüneyt tomruk

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.

Page 21: 9.hafta cüneyt tomruk

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,

Page 22: 9.hafta cüneyt tomruk

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

Page 23: 9.hafta cüneyt tomruk

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.

Page 24: 9.hafta cüneyt tomruk

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

Page 25: 9.hafta cüneyt tomruk

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.

Page 26: 9.hafta cüneyt tomruk

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.

Page 27: 9.hafta cüneyt tomruk

* 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.

Page 28: 9.hafta cüneyt tomruk

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.

Page 29: 9.hafta cüneyt tomruk

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'

Page 30: 9.hafta cüneyt tomruk

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ı

Page 31: 9.hafta cüneyt tomruk

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;

Page 32: 9.hafta cüneyt tomruk

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'

Page 33: 9.hafta cüneyt tomruk

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.

Page 34: 9.hafta cüneyt tomruk

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.

Page 35: 9.hafta cüneyt tomruk

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

Page 36: 9.hafta cüneyt tomruk

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'

Page 37: 9.hafta cüneyt tomruk

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.

Page 38: 9.hafta cüneyt tomruk

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?

Page 39: 9.hafta cüneyt tomruk

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;

Page 40: 9.hafta cüneyt tomruk

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.