Recent comments

None


İçerik Ara











Yasal Uyarı
Bu sitede sunulan tüm bilgi ve dökümanlar Turgay Sahtiyan tarafından yazılmaktadır. Yazıların kaynak göstermek şartıyla kullanılması serbesttir.

© Copyright 2009-2013
Takvim
<<  Haziran 2017  >>
PaSaÇaPeCuCuPa
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
Keywords

UNION ve UNION ALL 1 den fazla result set i birleştirip tek bir result set olarak almak için kullanılır.

EXCEPT ve INTERSECT ise table lar arasındaki farkı veya kesişimi result set olarak görüntülemek için kullanılır.

Denemeler yapmak için aşağıdaki sql script i Management Studio da uygulayın.

USE [AdventureWorks]
GO
--1.table ı create edelim
CREATE TABLE [dbo].[CustTable1](
	[Name] varchar(20) NULL,
	[SurName] varchar(20) NULL
) ON [PRIMARY]

--2.table ı create edelim
CREATE TABLE [dbo].[CustTable2](
	[Name] varchar(20) NULL,
	[SurName] varchar(20) NULL
) ON [PRIMARY]

--1.table ı dolduralım
INSERT INTO CustTable1(Name,SurName)
VALUES
('Turgay','Sahtiyan')
,('Turgay','Yýlmaz')
,('Bill','Gates')
,('Bruce','Willis')

--2.table ı dolduralım
INSERT INTO CustTable2(Name,SurName)
VALUES
('Turgay','Sahtiyan')
,('Turgay','Gates')
,('Martina','Navratilova')
,('Pete','Sampras')
,('Bruce','Willis')

Table ların şu andaki durumuna bakalım.

SELECT * FROM CustTable1
SELECT * FROM CustTable2

image

UNION


Verilen result setleri birleştirip tek bir result set oluşturur. Aynı olan kayıtlar süzülür ve 1 kez getirilir. Örn Turgay Sahtiyan 2 table da geçmesine rağmen son result set te 1 kere bulunmaktadır.

SELECT Name,SurName from CustTable1
UNION
SELECT Name,SurName from CustTable2

image

UNION ALL


Verilen result setleri birleştirip tek bir result set oluşturur. Aynı olan kayıtlar süzülmez tekrar tekrar getirilir. Örn Turgay Sahtiyan son result set te 2 defa bulunmaktadır.

SELECT Name,SurName from CustTable1
UNION ALL
SELECT Name,SurName from CustTable2

image

 

EXCEPT


İlk result set te olup 2. Result set te olmayan kayıtları getirir. Örn Bill Gates ilk table da var ama 2.table da yok. Son result set te bu kayıt bulunacaktır.

SELECT Name,SurName from CustTable1
EXCEPT
SELECT Name,SurName from CustTable2

image  

INTERSECT


Verilen 2 result set in kesişimini getirir. Örn Turgay Sahtiyan her 2 table da da bulunmaktadır. Son result set te bu kayıt bulunacaktır.
SELECT Name,SurName from CustTable1
INTERSECT
SELECT Name,SurName from CustTable2

image

Yukarıda açıklanan ifadeler ile bazı diğer T-SQL ifadeleri beraber kullanılabilmektedir. Şimdi bu ifadelere bakalım.

INSERT INTO Kullanımı


Union veya diğer ifadelerle oluşturulmuş result set başka bir table a insert edilmek isteniyorsa sadece ilk table ın önüne INSERT INTO ifadesi yazılır. Diğer table larında önüne yazılırsa query hata verecektir.

Bu işlemi denemek için ilk önce bir table create edelim. Insert işlemini bu table ın içine yapacağız.

--3.table ı create edelim
CREATE TABLE [dbo].[CustTable3](
	[Name] varchar(20) NULL,
	[SurName] varchar(20) NULL
) ON [PRIMARY]

Şimdi union işlemi yaparak CustTable3 e insert yapalım.

INSERT INTO CustTable3
SELECT Name,SurName from CustTable1
UNION
SELECT Name,SurName from CustTable2

CustTable3 ün sonucuna bakalım.

SELECT * FROM CustTable3

image


ORDER BY Kullanımı


Bildiğiniz gibi ORDER BY ifadesi bir result set i istenilen kolona göre sıralamak yapmak için kullanılır. ASC ifadesi küçükten büyüğe, DESC ifadesi ise büyükten küçüğe doğru sıralama yapmak için kullanılır. Eğer 2 sıralama ifadeside belirtilmezse default olarak ASC kullanılır.

Union ve yukarıda bahsettiğimiz diğer ifadelerde order kullanımında Order ifadesi her bir table için yazılmaz. Order ifadesi en sona konulur ve en son birleştirilmiş result set in order edilmesi sağlanır.

SELECT Name,SurName from CustTable1
UNION ALL
SELECT Name,SurName from CustTable2
ORDER by Name ASC,SurName DESC

image


GROUP BY ve HAVING Kullanımı


Group by bir result set i gruplamak, Having ise gruplanmış ifadeleri filtrelemek için kullanılır.

Union ve yukarıda bahsettiğimiz diğer ifadelerde GROUP BY ve HAVING her table için yazılır.

SELECT Name from CustTable1
GROUP BY Name
UNION
SELECT Name from CustTable2
GROUP BY Name
ORDER BY Name

image

Yazımızın sonuna geldik. Umarım açıklayıcı bir yazı olmuştur.

İyi çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server da string ifadeleri saklamak için Char, VarChar, NChar ve NVarChar data tipleri kullanılmaktadır.

Peki hangi durumlarda bu 4 seçenekten hangisini kullanmak daha performanslı bir çözüm olur.

Genel hatlarıyla NChar ve NVarChar data tiplerinin UniCode ifade saklanması planlanan alanlar için kullanılmasında fayda vardır. Çünkü bu data tipler N siz olan versiyonlara göre 2 kat daha fazla yer kaplamaktadır.

VarChar ın Char dan farkı ise; Char,içindeki veri ne olursa olsun belirtildiği n değeri kadar yer kaplarken;varchar,içerisinde belirtildiği string kadar yer kaplar. Dolayısıyla tanımlanan alana girilecek bilgiler çoğunlukla aynı boyutta olacaksa Char kullanmak, farklı boyutta bilgiler girilecekse VarChar kullanmak daha mantıklıdır.

Reel hayattan bir örnek vermek gerekirse; Ad-SoyAd gibi alanlara girilecek bilgiler aynı boyutta olmayacaktır dolayısıyla böyle alanları varchar tanımlamak daha mantıklıdır. Posta Kodu ve Telefon gibi alanlara ise girilecek bilgiler çoğunlukla aynı boyutta olacaktır dolayısıyla bu alanlarıda char olarak tanımlamak daha mantıklı olacaktır.

Örneğin Char(10) diye tanımlanmış bir alana “TEST” ifadesi yazılırsa geri kalan kısma “ ” eklenecek ve reel data aslında “TEST ” şeklinde olacaktır.

Data tiplerinin storage de kapladıkları alanlar şu şekildedir; (n) genişliğinde tanımlama yapıldığı, ve değişkenin içine (l) uzunluğunda bir değer girildiği düşünülürse;

Data Type

(n) Değeri

Storage de Kapladığı Alan

Char (n) (l)

1 – 8000

N

VarChar (n) (l)

1 – 8000

l + 2

NChar (n) (l)

1 – 4000

2 * n

NVarChar (n) (l)

1 – 4000

2*l + 2

 

Örneğin NChar(10) olarak tanımlanmış bir alana “test” string i girilirse bu alan storage de 2*10 = 20 byte lık bir alan kaplayacaktır.

Aynı örnek için;

  • Char -> 10 byte
  • VarChar -> 4+2=6 byte
  • NChar -> 2*10 = 20 byte
  • NVarChar -> 2*4+2=10 byte

Yer kaplayacaktır.

Bu alanları birde Management Studio üzerinde test edip yazımızı sonlandıralım.

Aşağıdaki sql query i Management Studio da çalıştırın.

DECLARE @dt_char char(10)
       ,@dt_varchar varchar(10)
	   ,@dt_nchar nchar(10)
       ,@dt_nvarchar nvarchar(10)
       
SELECT @dt_char = 'TEST'
      ,@dt_varchar = 'TEST'
      ,@dt_nchar = 'TEST'
      ,@dt_nvarchar = 'TEST' 
      
SELECT 'Char' as DataType,DATALENGTH(@dt_char) as Boyut
UNION ALL
SELECT 'VarChar' as DataType,DATALENGTH(@dt_varchar)+2 as Boyut
UNION ALL
SELECT 'NChar' as DataType,DATALENGTH(@dt_nchar) as Boyut
UNION ALL
SELECT 'NVarChar' as DataType,DATALENGTH(@dt_nvarchar)+2 as Boyut

image

Gördüğünüz gibi data tiplerinin kapladıkları alanlar query sonucunda olduğu gibi.

İyi çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Disaster durumlarından geri dönüşlerde yada herhangi bir ihtiyaç duyulduğunda 2 table ı row bazında karşılaştırma ihtiyacı doğabilir. Böyle bir durum SQL Server DBA için oldukça sıkıcı bir durumdur.

SQL Server 2005 ile beraber gelen TableDiff.exe bu ihtiyaca oldukça yeterli çözüm sağlamaktadır.

Temel syntax ı şu şekildedir;

tablediff 
[ -? ] | 
{
        -sourceserver source_server_name[\instance_name]
        -sourcedatabase source_database
        -sourcetable source_table_name 
    [ -sourceschema source_schema_name ]
    [ -sourcepassword source_password ]
    [ -sourceuser source_login ]
    [ -sourcelocked ]
        -destinationserver destination_server_name[\instance_name]
        -destinationdatabase subscription_database 
        -destinationtable destination_table 
    [ -destinationschema destination_schema_name ]
    [ -destinationpassword destination_password ]
    [ -destinationuser destination_login ]
    [ -destinationlocked ]
    [ -b large_object_bytes ] 
    [ -bf number_of_statements ] 
    [ -c ] 
    [ -dt ] 
    [ -et table_name ] 
    [ -f [ file_name ] ] 
    [ -o output_file_name ] 
    [ -q ] 
    [ -rc number_of_retries ] 
    [ -ri retry_interval ] 
    [ -strict ]
    [ -t connection_timeouts ] 
}

Şimdi denemeler yapmak için bazı table lar create edip içlerini dolduralım.

--database create et
CREATE DATABASE DBDiff

--1.table
CREATE TABLE [dbo].[TableDiff1](
	[id] [int] NOT NULL,
	[Ad] [varchar](50) NULL,
	[SoyAd] [varchar](50) NULL,
 CONSTRAINT [PK_TableDiff1] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

--2.table
CREATE TABLE [dbo].[TableDiff2](
	[id] [int] NOT NULL,
	[Ad] [varchar](50) NULL,
	[SoyAd] [varchar](50) NULL,
 CONSTRAINT [PK_TableDiff2] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

--1.table ı doldur
INSERT INTO TableDiff1(id,Ad,Soyad) VALUES (1,'Turgay','Sahtiyan');
INSERT INTO TableDiff1(id,Ad,Soyad) VALUES (3,'Ahmet','Mehmet');
INSERT INTO TableDiff1(id,Ad,Soyad) VALUES (5,'Veli','Deli');
  
--2.table ı doldur
INSERT INTO TableDiff2(id,Ad,Soyad) VALUES (1,'Turgay','Sahtiyan');
INSERT INTO TableDiff2(id,Ad,Soyad) VALUES (3,'Ahmet','Ahmet');
INSERT INTO TableDiff2(id,Ad,Soyad) VALUES (4,'Murtaza','Kirmizi');

Table ların şu anki durumlarına bakacak olursak;

SELECT * from TableDiff1  
SELECT * from TableDiff2

image

Şimdi aşağıdaki verileri doldurarak ilk karşılaştırmamızı yapalım;

  • sourceserver : Kaynak server ın adı. Instance varsa \ şeklinde instance da eklenmelidir
  • sourcedatabase : Kaynak Veritabanı Adı
  • sourcetable : Kaynak Table
  • destinationserver : Hedef server ın adı.
  • Instance varsa kullanılmalı.
  • destinationdatabase : Hedef Veritabanı Adı
  • destinationtable : Hedef Table ın adı.

Karşılaştırmalar her zaman kaynak bilgiler baz alınarak yapılır. Hedef table kaynak table a benzetilmeye çalışılır.

İlk karşılaştırmamız için aşağıdaki kod bloğunu command prompt ta çalıştıralım.

"C:\Program Files\Microsoft SQL Server\100\COM\tablediff.exe" –sourceserver SAHTIYAN_T\SQL10ENT -sourcedatabase DBDiff -sourcetable tablediff1 –destinationserver SAHTIYAN_T\SQL10ENT -destinationdatabase DBDiff -destinationtable TableDiff2

Sonuç:

Microsoft (R) SQL Server Replication Diff Tool
Copyright (c) 2008 Microsoft Corporation

User-specified agent parameter values:
-sourceserver SAHTIYAN_T\SQL10ENT
-sourcedatabase DBDiff
-sourcetable tablediff1
-destinationserver SAHTIYAN_T\SQL10ENT
-destinationdatabase DBDiff
-destinationtable TableDiff2

Table [DBDiff].[dbo].[tablediff1] on SAHTIYAN_T\SQL10ENT and Table [DBDiff].[dbo].[TableDiff2] on SAHTIYAN_T\SQL10ENT have 3 differences.
Err id
Mismatch 3
Dest. Only 4
Src. Only 5
The requested operation took 0,109375 seconds.

3 kayıdın tutmadığı bilgisini aldık ama bunların hangi kayıtlar olduğu hakkında bir fikrimiz yok.

Bu bilgiyide almak için –et parametresini kullanıyoruz. –et parametresi ile ismini verdiğimiz table ı create edip farklı olan kayıtları bu table ın içine atıyoruz. Eğer olan bir table ı kullanıyorsak –et yerine –dt kullanmamız gerekmekte yoksa table olduğu için ve tekrar create etmeye çalışacağı için hata verecektir.

Z:\>"C:\Program Files\Microsoft SQL Server\100\COM\tablediff.exe" –sourceserver SAHTIYAN_T\SQL10ENT -sourcedatabase DBDiff -sourcetable tablediff1 -destinationserver SAHTIYAN_T\SQL10ENT -destinationdatabase DBDiff -destinationtable TableDif f2 -et DifferenceTbl

Bu işlem sonucunda DifferenceTbl dolmuş olacaktır.

select * from DifferenceTbl

image

Gelen bu sonuca baktığımızda gene pek anlaşılır bir sonuç olmadığını görüyoruz.Hangi kayıtların tutmadığını bilgisi var ama tutmayan bilgiler nedir bunu göremiyoruz.

Şimdi kullanacağımız bir diğer parametre olan –f parametresi ise bize oldukça detay bilgi verecektir. Bu parametre vasıtasıyla hedef table ı kaynak table a benzetmek için uygulanması gereken sql komutlarını bir dosyanın içinde toplayabiliyoruz.

Z:\>"C:\Program Files\Microsoft SQL Server\100\COM\tablediff.exe" –sourceserver
SAHTIYAN_T\SQL10ENT -sourcedatabase DBDiff -sourcetable tablediff1 -destinationserver SAHTIYAN_T\SQL10ENT -destinationdatabase DBDiff -destinationtable TableDiff2 -et DifferenceTbl -f c:\TableDiff.sql

c:\TableDiff.sql dosyasına bakacak olursak;

-- Host: SAHTIYAN_T\SQL10ENT
-- Database: [DBDiff]
-- Table: [dbo].[TableDiff2]
UPDATE [dbo].[TableDiff2] SET [SoyAd]=N'Mehmet' WHERE [id] = 3
DELETE FROM [dbo].[TableDiff2] WHERE [id] = 4
INSERT INTO [dbo].[TableDiff2] ([Ad],[id],[SoyAd]) VALUES (N'Veli',5,N'Deli')

 

Son olarak –bf parametresine bakalım. Bu parametre ile de sql komutlarına yerleştirdiğimiz dosyanın alabileceği maksimum satır sayısını belirleyebiliyoruz. Mesela bu örnek için bu parametreyi 1 olarak kullanırsak;

Z:\>"C:\Program Files\Microsoft SQL Server\100\COM\tablediff.exe" –sourceserver
SAHTIYAN_T\SQL10ENT -sourcedatabase DBDiff -sourcetable tablediff1 -destinationserver SAHTIYAN_T\SQL10ENT -destinationdatabase DBDiff -destinationtable TableDiff2 -et DifferenceTbl -f c:\TableDiff.sql -bf 1

3 tane dosya oluşacak ve her dosyanın içinde 1 satır sql komutu bulunacaktır.

TableDiff.0.sql

-- Host: SAHTIYAN_T\SQL10ENT
-- Database: [DBDiff]
-- Table: [dbo].[TableDiff2]
UPDATE [dbo].[TableDiff2] SET [SoyAd]=N'Mehmet' WHERE [id] = 3

 

TableDiff.1.sql

-- Host: SAHTIYAN_T\SQL10ENT
-- Database: [DBDiff]
-- Table: [dbo].[TableDiff2]
DELETE FROM [dbo].[TableDiff2] WHERE [id] = 4

 

TableDiff.2.sql

-- Host: SAHTIYAN_T\SQL10ENT
-- Database: [DBDiff]
-- Table: [dbo].[TableDiff2]
INSERT INTO [dbo].[TableDiff2] ([Ad],[id],[SoyAd]) VALUES (N'Veli',5,N'Deli')

 

TableDiff.exe nin kullanımı bu şekilde. Umarım açıklayıcı bir yazı olmuştur.

Kolay gelsin

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server da BackUp seçeneklerinden 2 si Full ve Differential BackUp seçeneğidir.

Full BackUp da database in tamamının yedeği alınmakta, Differential BackUp seçeneğinde ise sadece en son alınmış Full BackUp tan sonraki değişikliklerin BackUp ı alınmaktadır.

Full BackUp tan direk bir database recovery edilebilirken, Differential BackUp ise Full BackUp ile recovery edilmiş bir database üzerine uygulanır.

Bu uygulama esnasında Full BackUp recovery edilirken unutulan bir özellik, Differential BackUp recovery işleminde başlıktaki hatayı verebilmektedir.

The log or differential backup cannot be restored because no files are ready to rollforward.

image

Unutulan bu özellik; Recovery – Options ekranındaki NoRecovery özelliğidir.

image

Full BackUp yapılırken yukarıdaki seçenek işaretlenip daha sonra Differential BackUp yapılırsa herhangi bir problem oluşmayacaktır.

Kolay gelsin

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Bir subquery de belli bir kolonun bütün değerlerini belli bir değer ile karşılaştırıp tamamı(ALL) sağlıyorsa TRUE yada en az biri(SOME-ANY) sağlıyorsa TRUE değeri döndürebiliriz.

Base olarak syntax ı şu şekildedir;

Karsilastirma_ifadesi { = | <> | != | > | >= | !> | < | <= | !< } ALL ( subquery )

Karsilastirma_ifadesi { = | < > | ! = | > | > = | ! > | < | < = | ! < } { SOME | ANY } ( subquery )

Argümanlar;

= | < > | ! = | > | > = | ! > | < | < = | ! < : Karşılaştırma için kullanılabilecek operatörler

ALL | SOME | ANY : Karşılaştırma tipi.

  • ALL : Subquery de ki kolon daki bütün verilerin şartı sağlaması gerekmektedir.
  • SOME | ANY : 2 si birbirinin tamamiyle aynısıdır. Subquery de ki kolon daki verilerin en az birinin şartı sağlaması yeterlidir.

Subquery de çağrılan kolonun veri tipi ile karşılaştırma ifadesinin veri tipi birbirinin aynı olması gerekmektedir.

Aşağıdaki table ı create edip içini veri ile dolduralım.

CREATE TABLE Tbl_Sample
(ID int, Value float) ;
GO
INSERT Tbl_Sample VALUES (1,100) ;
INSERT Tbl_Sample VALUES (2,200) ;
INSERT Tbl_Sample VALUES (3,300) ;
INSERT Tbl_Sample VALUES (4,400) ;

Aşağıdaki sorgu ile de denemelerimizi yapalım.

DECLARE @ValueTmp float=550

IF @ValueTmp< ALL (SELECT Value from Tbl_Sample)
  PRINT 'Bütün deðerler '+CAST(@ValueTmp as varchar(5))+' den büyüktür.'
ELSE
  PRINT 'Bütün deðerler '+CAST(@ValueTmp as varchar(5))+' den büyük deðildir.'
  
IF @ValueTmp< ANY (SELECT Value from Tbl_Sample)
  PRINT 'En az 1 deðer '+CAST(@ValueTmp as varchar(5))+' den büyüktür.'
ELSE
  PRINT 'Bütün deðerler '+CAST(@ValueTmp as varchar(5))+' den küçüktür'


DECLARE @ValueTmp float=50 için sonuç;
Bütün değerler 50 den büyüktür.
En az 1 değer 50 den büyüktür.

DECLARE @ValueTmp float=250 için sonuç;
Bütün değerler 250 den büyük değildir.
En az 1 değer 250 den büyüktür.

DECLARE @ValueTmp float=450 için sonuç;
Bütün değerler 450 den büyük değildir.
Bütün değerler 450 den küçüktür

 

İyi çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Sp_monitor SQL Server hakkında istatistikleri görmemize yarayan sistem prosedürüdür.

Kullanılabilmesi için sysadmin role üne sahip olunması gerekmektdir.

Kullanımı;

EXEC sp_monitor

image

Bilgi kolonlarının açıklamaları şu şekildedir;

Last_run : sp_monitor ü en son çalıştırdığımız zamanı gösterir.

Current_run : Şu an çalıştırdığımız sp_monitor ün tam olarak çalıştırılma zamanını gösterir.

Seconds : Current_run ile Last_run arasındaki saniye farkını gösterir.

Cpu_busy : CPU nun saniye cinsinden SQL Server işleri yaptığı süreyi verir.

İo_busy : SQL Server ın input output için harcadığı süreyi saniye cinsinden verir.

İdle : SQL Server ın idle süresini saniye cinsinden verir.

Packets_received : SQL Server tarafından okunan input packet sayısını verir.

Packets_sent : SQL Server tarafından yazılan output packet sayısını verir.

Packet_errors : SQL Server okuma ve yazma işlemi sırasında karşılaşılan hatalı packet sayısını verir.

Total_read : SQL Server ın yaptığı okuma sayısını verir.

Total_write : SQL Server ın yaptığı yazma sayısını verir.

Total_errors : SQL Server ın okuma ve yazma yaptığı sırada karşılaşılan hata sayısı verir.

Connections : SQL Server a yapılan toplam erişim denemesini verir.

sp_monitor çıktısına tekrar bakacak olursanız kolonların genellikle sayı1(sayı2)-sayı3% yada sayı1(sayı2) şeklinde ifade edildiklerini göreceksiniz.

İlk tip için sayı1 SQL Server restart ından itibaren geçen toplam saniyeyi(örn cpu_busy), sayı2 bir önceki sp_monitor den sonra geçen süreyi(gene cpu_busy), sayi3 ise sayi2 nin seconds kolonuna oranıdır.

Örneğin; idle kolonundaki 8754(806) – 193% bilgisi için;

  • 8754, SQL Server restart edildikten itibaren toplam idle süresinin saniye cinsinden karşılığıdır.
  • 806, bir önceki sp_monitor den sonra gerçekleşen idle süresinin saniye cinsinden karşılığıdır.
  • %193 ise 806 nın seconds yani toplam geçen süre kolonuna oranıdır.

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2005 elen gelen coalesce fonksiyonu, aldığı argümanlardan null olmayan ilkini geri döndürür.

MSDN library de bulunan örneği vererek açıklamaya çalışacağım.

SET NOCOUNT ON;
SET NOCOUNT ON;
GO
USE tempdb;
IF OBJECT_ID('dbo.wages') IS NOT NULL
    DROP TABLE wages;
GO
CREATE TABLE dbo.wages
(
    emp_id        tinyint   identity,
    hourly_wage   decimal   NULL,
    salary        decimal   NULL,
    commission    decimal   NULL,
    num_sales     tinyint   NULL
);
GO
INSERT dbo.wages (hourly_wage, salary, commission, num_sales)
VALUES
    (10.00, NULL, NULL, NULL),
    (20.00, NULL, NULL, NULL),
    (30.00, NULL, NULL, NULL),
    (40.00, NULL, NULL, NULL),
    (NULL, 10000.00, NULL, NULL),
    (NULL, 20000.00, NULL, NULL),
    (NULL, 30000.00, NULL, NULL),
    (NULL, 40000.00, NULL, NULL),
    (NULL, NULL, 15000, 3),
    (NULL, NULL, 25000, 2),
    (NULL, NULL, 20000, 6),
    (NULL, NULL, 14000, 4);
GO
SET NOCOUNT OFF;
GO
SELECT CAST(COALESCE(hourly_wage * 40 * 52, 
   salary, 
   commission * num_sales) AS money) AS 'Total Salary' 
FROM dbo.wages
ORDER BY 'Total Salary';

 

Sonuç;

Total Salary
------------
20800.0000
41600.0000
62400.0000
83200.0000
10000.0000
20000.0000
30000.0000
40000.0000
45000.0000
50000.0000
120000.0000
56000.0000

Örneğimizde gördüğümüz gibi maaş ödemeleri için 3 seçenek bulunuyor.

  • Saatlik ücret
  • Aylık maaş
  • Komisyon

Çalışanların anlaşması bu 3 değişik modelden biri olabiliyor. Biz bunlarınhepsini tek bir sorguda vermek için COALESCE(hourly_wage,salary,commission) yapısını kullanıyoruz.

Bu yapıya göre hourly_wage null deil ise onu kullanıyor. Null ise bir sonraki argüman olan salary e bakıp null değilse onu kullanıyor. Oda null sa bir sonraki argüman a geçip ona bakıyor.

Umarım açıklayıcı olmuştur. Görüşmek üzere

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Hepimiz bloglarımızda kullandığımız code ların daha okunur olması için kod renklendirici yani syntaxhighlighter kullanırız. Ama piyasada bulunan bazı çözümler işimizi kolaylaştırmakı daha çok zorlaştırmak için adanmış sanki.

Bende bu çözümlerden biriyle baya bir cebelleştikten sonra değiştirme kararı aldım ve başka bir syntaxhighlighter kullanmaya başladım.

Şimdi size bu code renklendiricinin blog engine de nasıl kullanacağı hakkında bilgi vereceğim.

İlki olarak code dosyalarını aşağıdaki adresten indiriniz.

http://alexgorbatchev.com/downloads/grab.php?name=sh

İndirdiğiniz zip dosyasını açın ve blogengine web hostinginizce “syntaxhighlighter” diye bir klasör create edip bunun içine atın.

Daha sonra blogengine de admin kısmından ayarlar a gelin ve “HTML Head Section” kısmına aşağıdaki kodları ekleyin.

<script type="text/javascript" src="/syntaxhighlighter/scripts/shCore.js"></script>
  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushBash.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushCpp.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushCSharp.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushCss.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushDelphi.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushDiff.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushGroovy.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushJava.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushJScript.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushPhp.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushPlain.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushPython.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushRuby.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushScala.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushSql.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushVb.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushXml.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushPowerShell.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushPerl.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushJavaFX.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushAS3.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushJScript.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushColdFusion.js"></script>

  <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushErlang.js"></script>

  <l rel="stylesheet" type="text/css" href="/syntaxhighlighter/styles/shCore.css" INK>

  <l rel="stylesheet" type="text/css" href="/syntaxhighlighter/styles/shThemeDefault.css" INK>

  <script type="text/javascript">

  SyntaxHighlighter.config.clipboardSwf = '/syntaxhighlighter/scripts/clipboard.swf';

  SyntaxHighlighter.all();

  </script>

 

Son olarak post unuzda code bloğu kullanırken bunu <pre class="brush: c-sharp;"> </pre> tagları içine alınız.

c# için –> c-sharp
sql için –> sql
css için –> css
javascript için –> js kullanabilirsiniz.

 

Daha detaylı bir anlatımı aşağıdaki adreste bulabilirsiniz.

http://www.tellingmachine.com/post/Setting-up-SyntaxHighligther-for-BlogEngineNET-in-the-bare-bone-fashion.aspx

 

Kolay gelsin

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Relational Database lerin temelini adı üstünde relation oluşturmaktadır. Sistemimizde bulunan tablolardan raporlama yapmak istediğimiz de bu tabloları birbirine bağlayarak sorgulamamız gerekmektedir. Örneğin Sipariş bilgilerini tuttuğumuz bir veritabanı düşünelim. Böyle bir veritabanı yapısında sipariş no,sipariş tarihi,sipariş carisi gibi üst bilgileri Siparis_M tablosunda, stok ve miktar bilgilerini ise Siparis_D tablosunda tutarız. Eğer ki “ya iyide bunları neden tek tabloda tutmuyoruz da ayrı tablolarda tutuyoruz?” diyorsanız bence bu makaleden önce “Relational Database” hakkında bir yazı okumanız daha faydalı olacaktır. :)

Siparis_M ve Siparis_D tablolarında siparişlerimizi tuttuk okey. Peki zamanı geldiğinde bunları nasıl birleştirip raporlayacağız. Yani örneğin “geçen ay alınan tüm siparişler” yada “ahmet carisinin aldığı siparişler” sorusuna cevap verebilmemiz için bu 2 tabloyu birbirine bağlayarak raporlamamız gerekmektedir.

İşte SQL Serverda birden fazla table ı birbirine bağlamak için join keyword u kullanılır ve Syntax ı şu şekildedir;

FROM Table1	
{LEFT | RIGHT | FULL} [OUTER] JOIN table2 ON condition


Örneğin sipariş master tablosuna sipariş detay tablosunu bağlayalım;

SELECT sm.*,sd.*
FROM Siparis_M sm
LEFT JOIN Siparis_D sd on sd.SipNo=sm.SipNo

Peki join keyword unu kullanırken LEFT,RIGHT gibi join typle larını görüyoruz. Şimdi bunları tek tek örnekleyerek açıklamaya çalışalım. Bu arada bu işlemlerin hepsi SQL Server 2008 de yapılmıştır.


Denemelerimizi yapabilmek için önce 2 tane table tanımlayacağız. Bunlardan ilki Sipariş Master bilgilerini tutacak olan Siparis_M table ı, diğeri ise Sipariş Detail bilgilerini tutacak olan Siparis_D table ı olacak.

Bu table ları create etmek için aşağıdaki kodu SSMS (SQL Server Management Studio) da uygulayınız.

USE [AdventureWorks]
GO
CREATE TABLE [dbo].[Siparis_M](
	[SipNo] [int] NULL,
	[SipTar] [datetime] NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[Siparis_D](
	[SipNo] [int] NULL,
	[SipHarID] [int] NULL,
	[StokKod] [varchar](50) NULL,
	[Miktar] [float] NULL
) ON [PRIMARY]

Bu 2 table ı SipNo field i ile birbirine bağlayacağız.

Şimdi table ların içine bazı veriler dolduralım. Bunun için aşağıdaki sql i SSMS da uygulayınız.

INSERT INTO Siparis_M(SipNo,SipTar)
VALUES 
(1,GETDATE()+1)
,(2,GETDATE()+1)
,(3,GETDATE()+1)
,(4,GETDATE()+1)
,(NULL,GETDATE()+1)
,(NULL,GETDATE()+1)

INSERT INTO Siparis_D(SipNo,SipHarID,StokKod,Miktar)
VALUES 
(1,1,'a',15)
,(1,2,'b',25)
,(3,3,'c',35)
,(3,4,'d',45)
,(3,5,'e',55)
,(5,6,'f',65)
,(6,7,'g',75)
,(null,8,'h',85)
,(null,null,'i',95)

Tablolarımız son durumunu görmek için aşağıdaki kodu SSMS da uygulayalım.

SELECT * FROM Siparis_M
SELECT * FROM Siparis_D

image_thumb

Gördüğünüz gibi Siparis_M de olan bazı SipNo lar Siparis_D de yok. Aynı şekilde Siparis_D de olup Siparis_M de olmayan SipNo larda var. Aslında düzgün çalışan bir Relational Database de bu tarz kayıtlar olmaz. Ben Join Type ları daha rahat bi şekilde açıklayabilmek için bu şekilde bir data yapısı kurmayı uygun buldum.

Evet, artık tablolarımız kullanılmaya hazır. Şimdi join type larını tek tek inceleyelim.

 

LEFT (OUTER) JOIN

Soldaki table baz alınarak sağdaki table soldakine eklenir. Yani soldaki tableda olan bilgi sağdakinde yoksa bile sonuçta gösterilir. Ama sağdaki bilgi solda yoksa gösterilmez. Burada ki sol sağ kavramı ilk ve ikinci table manasına gelmektedir. (Yada bağlanılan ve bağlanan)

OUTER bilgisi opsiyonaldir. Yazılmasa dahi OUTER olarak işlem yapılır. LEFT JOIN in INNER type ı bulunmaktadır.

Şimdi siparis_d table ını siparis_m table ına LEFT JOIN ile bağlayalım.

SELECT sm.SipNo,sm.SipTar,sd.SipHarId,sd.StokKod,sd.Miktar
FROM Siparis_M sm
LEFT JOIN Siparis_D sd on sd.SipNo=sm.SipNo

image_thumb1

Gördüğünüz gibi siparis_m deki bütün sipariş numaraları sorguda gelmiş, ama siparis_d de bulunan bazı siparis no lar gelmemiş.(Örneğin Siparis_D de bulunan 5 ve 6 SipNo lu kayıtlar sorgu sonucu gelmemiştir.) Bunun sebebide join type olarak LEFT JOIN kullanmamız.

Bunun tam tersini yapmak için, yani sağdakilerin tamamının gelmesini ama solda olup sağda olmayanların gelmemesi için RIGHT JOIN kullanılmalıdır.

 

RIGHT (OUTER) JOIN

Yukarıda da belirttiğim gibi sağdaki yani bağlanan table baz alınılarak işlem yapılır. Örnekte daha rahat anlayacağınıza eminim.

SELECT sm.SipNo,sm.SipTar,sd.SipHarId,sd.StokKod,sd.Miktar
FROM Siparis_M sm
RIGHT JOIN Siparis_D sd on sd.SipNo=sm.SipNo

image_thumb2

Gördüğünüz gibi siparis_d table ının tamamı sorgu sonucunda gelmiştir. Ama Siparis_M de olup Siparis_D de olmayan(Örneğin SipNo su 2 olan kayıt) kayıtlar sorgu sonucunda gelmemiştir.


INNER JOIN

Inner join bağlanan ve bağlanılan table ın 2 sinde birden geçen kayıtları getirmektedir. Yani bir kayıdın gelebilmesi için hem 1.Table da hemde 2.Table da geçmesi gerekmektedir.

SELECT sm.SipNo,sm.SipTar,sd.SipHarId,sd.StokKod,sd.Miktar
FROM Siparis_M sm
INNER JOIN Siparis_D sd on sd.SipNo=sm.SipNo

image_thumb3

Gördüğünüz gibi SipNo bazında sadece 2 table da birden olan kayıtlar gelmiş. Örneğin Siparis_M de bulunan 2 nolu sipariş Siparis_D de olmadığı için gelmemiştir. Aynı şekilde Siparis_D de olan 5 ve 6 nolu siparişler Siparis_M de olmadığı için gelmemiştir.

Bütün kayıtların getirilmesi için FULL (OUTER) JOIN ifadesi kullanılmaktadır.


FULL (OUTER) JOIN

Kayıt,bağlanan veya bağlanılan tabloların herhangi birinde varsa getirilir. Bir bakıma birleştirme olarak düşünülebilir.

SELECT sm.SipNo,sm.SipTar,sd.SipHarId,sd.StokKod,sd.Miktar
FROM Siparis_M sm
FULL JOIN Siparis_D sd on sd.SipNo=sm.SipNo

image_thumb4

Görüldüğü gibi 1 ve 2. Table lar mixlenmiştir.

 

SQL Server da Join Type ları bu şekildedir. Umarım açıklayıcı bir yazı olmuş ve anlamışsınızdır :)

 

İyi çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Aşağıdaki sql cümlelerini yazıp execution planlarına bakalım.

SELECT *
FROM Sales.SalesOrderDetail
WHERE SalesOrderID>=43668 and SalesOrderID<=43670

SELECT *
FROM Sales.SalesOrderDetail
WHERE SalesOrderID BETWEEN 43668 and 43670

SELECT *
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43668,43669,43670)

image_thumb

Gördüğünüz gibi Between ile <= >= arasında hiç bir fark yok. IN komutuda çok az farklı.

Şu bundan daha iyi diye baştan hüküm vermek uygun değil. Kullanacağınız durumda execution planlarını bakıp karar vermek en mantıklısı.

Ben genelde aralık ifade eden durumlarda <= >= kullanıyorum. Onun dışında tarih range lerinde de bunu kullanmaktayım.

In komutunu genelde range ifade edemediğim durumlarda kullanıyorum.

Between e ise külliyen gıcığım. :)


İyi çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Geçenlerde kafama takılan bu soruya ufak bir araştırma neticesinde şu yanıtı aldım.”Tamamiyle sıfır”. Distinct ile GroupBy arasında çalışma mantığı olarak hiç bir fark yoktur.

Bunu birde execution planda görelim.Aşağıdaki kod bloğunun execution planını alalım.

SELECT DISTINCT SalesOrderID
FROM Sales.SalesOrderDetail

SELECT SalesOrderID
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID

image_thumb

Görüldüğü gibi Distinct ile GroupBy tamamiyle aynı.

İyi çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Bildiğiniz üzere SQL Server da kayıt silmek için DELETE ve TRUNCATE deyimleri kullanılmakta. Bu 2 si arasındaki en belirgin fark DELETE komutu ile belli bir aralığı silebilirken TRUNCATE komutu ile table ın tamamı silinmektedir.

Peki aralarındaki tek fark bu mu? Tabiki değil, diğer farkları aşağıda madde madde sıralamaya çalıştım.

1. TRUNCATE komutu ile parçalı silme yapılamazken DELETE komutu ile WHERE clause kullanılarak parçalı silme yapılabilmektedir.

2. DELETE komutu ile yapılan kayıt silme işleminde her silinen kayıt Transaction Log da kayıt bazında loglanmaktadır. TRUNCATE de ise loglama işlemi kayıt bazında yapılmamaktadır. Bu yüzden TRUNCATE komutu DELETE komutuna oranla büyük tablolarda inanılmaz hızlıdır.

3. Loglamadan dolayı DELETE işleminden sonra Transaction Log dosyası büyümektedir. Eğer büyüme açısından DELETE in TRUNCATE ile aynı sonucu vermesini istiyorsanız aşağıdaki kod bloğunu kullanabilirsiniz.

DELETE from "table_name" 
DBCC CHECKIDENT("table_name", RESEED, "reseed_value")

4. Eğer silme yapılan tabloda identity column var ise; TRUNCATE işleminden sonra bu kolon 1 den başlamakta, DELETE işleminden sonra ise kaldığı yerden devam etmektedir.

5. Foreign key içeren tablolarda TRUNCATE işlemi yapılamaz. Çünkü Foreign key e bağlı olan kayıtlarında silinebilmesi için table ın triger lanması gerekmekte ama TRUNCATE işleminde daha öncede söylediğim gibi loglama işlemi gerçekleşmemektedir. Genede TRUNCATE kullanmak istiyorsanız önce Foreign key in kaldırılması sonra TRUNCATE in yapılması ve daha sonrada Foreign Key in tekrar tanımlanması gerekmektedir.

6. Foreign key içeren tablolar DELETE ile silinmek zorundadır, ya da performanslı olmasını istiyorsanız işlemi DROP-CREATE şeklinde gerçekleştirebilirsiniz.

7. Ayrıca Trigger, Replication yada Log Shipping içeren tablolarda TRUNCATE kullanılmaz.


Son olarak DELETE ve TRUNCATE in execution planlarını karşılaştırıp yazımızı noktalayalım.

Bunun için ilk olarak bir table create edip içini 1000 kayıt ile dolduralım. Bu işlemler SQL Server 2008 de yapılmıştır.

USE [AdventureWorks]
CREATE TABLE [dbo].[tblSample](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[txt] [varchar](5) NULL,
 CONSTRAINT [PK_tblSample] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF
  , IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON
  , ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

declare @i int
set @i=1
while @i<=1000 begin
  insert tblSample select cast(@i as varchar(5))
  set @i=@i+1
end

Şimdide aşağıdaki komutları yazıp execution planlarına bakalım.

delete from tblSample

truncate table tblSample

image_thumb

İyi çalışmalar

Turgay Sahtiyan

Kaynaklar:

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server üzerindeki database lerimize daha sağlıklı çalışabilmesi için periyoduk olarak bakım yapmamız gerekmektedir. Aynı zamanda disaster durumları için periyodik olarak yedekleme işlemleride yaparız. Genelde yapılan işlemleri şu şekilde sıralayabiliriz;

  • Shrink (Boş Alanları Sıkıştırma) İşlemleri
  • Index Bakım İşlemleri (reIndex ve ReBuild)
  • BackUp Alma İşlemleri

Bu işlemleri manuel olarak yapmamız mümkün. Ama eğer birden fazla database varsa ve her gece belli bir saatte bu işlemleri yapmak istiyorsak bu durumda job ları devreye sokabiliriz.

SQL Server Maintenance Plan ise bize bu işlemleri belli bir plan içinde yapma şansı tanıyor. Aynı zamanda yapılan tanımlamayı tek bir yerden kontrol edebilme, aynı şekilde işlem sonucunuda tek bir yerden raporlama hakkı veriyor. Bu şekilde karmaşık yapılı veritabanı yönetiminde oldukça büyük rahatlık sağlamakta.

Şimdi isterseniz SQL Server 2008 de Maintenance Plan nasıl tanımlanır ve işletilir görelim.

Maintenance Plan menüsüne SQL Server Management Studio >> Management altından erişiyoruz.

mn1_thumb

Maintenance Plans a sağ tıklayıp yeni bir Maintenance Plan tanımlamak için “Maintenance Plan Wizard” a tıklıyoruz.

mn2_thumb

Gelen karşılama ekranında Next e basıp bir sonraki ekrana geçiyoruz.

mn3_thumb

Hazırladığımız maintenance plan a bir ad ve açıklama veriyoruz. Eğer birden fazla maintenance plan tasarlamayı düşünüyorsanız ad ve açıklama kısmına dikkat etmenizi tavsiye ederim.

Yapılan Maintenance ve BackUp işlemleri için schedule tanımlayabilir ve bu şekilde bu işlemleri periyodik olarak gerçekleşmesini sağlayabilirsiniz.

Bu işlemlerin her biri için ayrı ayrı schedule tanımlayabileceğiniz gibi hepsi için tek bir schedule da tanımlayabilirsiniz. Biz bu örneğimizde bütün işlemler için tek bir schedule tanımlayacağız. Ekrandaki radio butonu 2.seçenek olarak seçip schedule tanımlamak üzere Change butonuna basıyoruz.

mn4_thumb

Daha önceki yazılarımda SQL Server 2008 üzerinde Schedule (Job) tanımlamasını ayrıntılı anlattığım için burada tekrar anlatmıyorum. Schedule ile alakalı yazılarıma buradan erişebilirsiniz.

Biz bu ekranda işimizi 1 dakikada bir tekrarlatmak için 1 minute seçip OK e basıyoruz. Arka ekranda da Next e basıp bir sonraki ekrana geçiyoruz.

mn5_thumb

Bu ekranda Maintenance Plan dahilinde yapılması istenen işlemleri seçiyoruz. İşlemleri kendi bölümlerinde açıklayacağım. Ekranda ki bütün işlemleri seçip Next e basarak bir sonraki ekrana geçiyoruz.

mn6_thumb

Bir önceki ekranda seçtiğimiz işlemleri bu ekranda sıralayabiliriz. İşlemler yukarıdan aşağıya şekilde gerçekleştirilecektir. İstediğiniz sıralama değişikliklerini Move Up ve Move Down butonları vasıtasıyla yapabilirsiniz. Next e basıp bir sonraki ekrana geçiyoruz.

mn7_thumb

Bu aşamadan itibaren yapılacak işlemler için ayarlama tanımlamaları başlıyor.

Check Database Integrity : İstenilen database lerin bütünlüğünü ve sağlamlığını kontrol edip rapor verir. Database seçimi yapmak için Databases yazısının yanındaki combobox a tıklayıp database seçim ekranını açıyoruz.

mn8_thumb

Gelen ekranda istediğimiz databaseleri seçerek Ok e basıyoruz. Arka ekranda da Next e basıp bir sonraki ekrana geçiyoruz.

mn9_thumb

Shrink Database : Database lerdeki boş kullanılmayan alanları sıkıştırmaya yarar. Gerekli shrink ayarlarını yapıp database seçimini de yaptıktan sonra Next e basıyoruz. (Daha sonra bir yazımda Shrink i ayrıntılı ele almayı düşünüyorum. O yüzden burada çok detaylı bilgi vermeyeceğim.)

mn10_thumb

ReOrganize Index : Table ve view lerde kullanılan Index leri ReOrganize edip daha hızlı çalışmasını sağlayabiliriz. Database seçimini yapıp Index işleminin hangi Object lerde yapılmasını istediğimiz belirtip Next e basarak bir sonraki ekrana geçiyoruz.

mn11_thumb

ReBuild Index : Gene Index leri ReBuild ederek daha hızlı çalışmasını sağlayabiliriz. (Daha sonraki yazılarımda ReBuild ile ReOrganize arasındaki farklara değineceğim.) Database ve Object seçimini istediğimiz gibi yapıyoruz. Bu ekranda ayrıca “Keep Index online while reindexing” seçeneği bizim için çok önemli. Bu seçenek vasıtasıyla reindex işlemi yapılırken dahi index e erişimi kesmemiş oluyoruz. Next e basarak bir sonraki ekrana geçiyoruz.

mn12_thumb

Update Statistics : Veritabanı ile alakalı istatistik verilerinin update edilmesini yarayan bu ekranda table ve object seçimlerini yapıp Next e basıyoruz.

mn13_thumb

CleanUp History : Hazırlanan Maintenance Plan lar gerçekleştiğinde hdd de history dosyaları oluşturmaktadır. Bu ekranda bu oluşan history dosyalarının ne kadar süreyle hdd de saklanacağını seçebiliyorsunuz. İstenilen ayarlamaları yapıp Next e basıyoruz.

mn14_thumb

Execute SQL Server Agent Job : Daha önce başka işlemler için hazırladığınız SQL Server Job ları Maintenance Plan ın içine dahil edebilirsiniz. Bu ekranda eklemek istediğiniz Job ları seçip Next e basıyoruz.

mn15_thumb

BackUp Database (Full) : Bu ekranda FULL BackUp ının alınmasını istediğimiz Database leri belirliyoruz. Database seçimini yaptıktan sonra “Create a sub-directory for each database” yazısını işaretleyerek her database için bir klasör oluşmasını sağlıyoruz. Folder kısmına da BackUp ların alınacağı folder ı belirtiyoruz. Son olarak Compression Type ı seçerek Next e basıyoruz.

mn16_thumb

BackUp Database (Differential) : Differential BackUp alınmasını istediğimiz veritabanlarını bu ekranda belirliyoruz. Diğer ayarlamalar bir önceki ekrandaki gibidir. Next e basıp bir sonraki ekrana geçiyoruz.

mn17_thumb1

BackUp Database (Transaction Log) : Transaction Log BackUp alınmasını istediğimiz veritabanlarını bu ekranda belirliyoruz. Diğer ayarlamalar bir önceki ekrandaki gibidir. Next e basıp bir sonraki ekrana geçiyoruz.

mn18_thumb

Maintenance CleanUp Task : Maintenance Plan gerçekleşmeleri sonucunda oluşan BackUp ve Maintenance Plan Report dosyalarının hdd de ne kadar süre ile saklanacağını bu ekran vasıtasıyla ayarlayabilirsiniz. Gerekli ayarlamaları yapıp Next e basıyoruz.

mn19_thumb

Son olarak Maintenance Plan gerçekleştiğinde report dosyasının nereye oluşturulacağını ve bu sonucun mail olarak kime gönderileceğini seçerek Next e basıyoruz. Eğer SQL Server için mail ayarlarının anlatıldığı şu yazımı okumadıysanız okumanızı tavsiye ederim.

mn20_thumb

Yaptığımız Maintenance Plan ın bir summary si olan bu ekranı kontrol ettikten sonra Next e basıyoruz.

mn21_thumb

Ve son olarak close a basıp Maintenance Plan ı tanımlama işlemimizi bitiriyoruz.

Artık Maintenance Plan ımız hazır. Bu işlemin tamamlanmasından sonra Maintenance Plans kısmında ve Jobs kısmında 1 er yeni item oluşmuş olması lazım.

mn22_thumb mn23_thumb

Maintenance Plan a bir schedule atadığımız için burada atadığımız schedule Jobs kısmında görüntülenmekte.

Schedule 1 dakikada 1 olarak ayarlamıştık. Dolayısıyla her 1 dakikada 1 ayarladığımız bütün işlemler gerçekleşecektir. Biz genede bu işlemi elle çalıştırmak isteyebiliriz. Bunun için Maintenance Plans altından hazırladığımız Plan ı bulup sağ tıkla açılan ekranda Evecute e basabiliriz.

mn24_thumb

Bu işlem sonucunda Plan çalışmaya başlayacak ve aşağıdaki ekran açılacaktır.

mn25_thumb

Hata verirse bu ekranda message kısmında verdiği hatayı görebilirsiniz.

Son olarak oluşan backup dosyalarına HDD de bakalım ve yazımızı noktalayalım.

mn26_thumb

SQL Server 2008 de Maintenance Plan oluşturma ve yönetme işlemleri bu şekilde. Umarım açıklayıcı bir yazı olmuştur ve işinize yarar.

 

Kolay gelsin

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan