public partial class _DefaultPage
{
    protected override void Render(HtmlTextWriter writer)
    {
        Response.Clear();
        Response.Buffer = true;
        Response.ContentType = "application/msword";
        StringBuilder sb = new StringBuilder();
        StringWriter stringWriter = new StringWriter(sb);
        HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
        base.Render(htmlTextWriter);
        Response.Write(sb.ToString());
        Response.End();            
    }
}

 

Page nesnesi sayfadaki her kontrol için Render metodunu çağırır, bu metodu ezerek sonuçta tarayıcımızda göreceğimiz tüm HTML çıktısını Word dosyası olarak kaydedebiliyoruz.

 

ASP:NET Page Life Cycle

 

Her geçen gün daha çok firma SQL Server, Exchange Server, ve SharePoint Server gibi Microsoft uygulamaları ve diğer iş kritik uygulamaları için Microsoft Hyper-V sanallaştırma platformunu tercih ediyor. Bu firmalar, Microsoft Sanallaştırma Platformu ile kaynak kullanımında verimlilik, artan iş sürekliliği ile daha çevik ve etkili yönetim çözümüne sahip oluyorlar. Siz de Microsoft sanallaştırma çözümlerini ücretsiz ve kullanımı kolay bir portal aracılığıyla öğrenmek ve BT bilgilerinizi güncelleyerek kariyeriniz de bir adım öne çıkmak ister misiniz?

Microsoft Sanal Akademi tam size göre. Şu anda 23.000’den fazla katılımcı Microsoft Sanal Akademi aracılığıyla Microsoft Sanallaştırma teknolojilerini öğreniyor ve iş hayatına uyguluyor. Siz de bu ücretsiz eğitimlere katılıp, ücretsiz sınavlarla dünya çapında sıralama da üst sıralara çıkabilirsiniz.

Sürekli olarak yeni eğitimlerle güncellenen Microsoft Sanal Akademiye giriş için tıklayın.

 

 

 

select  SUBSTRING(st.text, (qs.statement_start_offset/2)+1,
  ((CASE qs.statement_end_offset
   WHEN -1 THEN DATALENGTH(st.text)
   ELSE qs.statement_end_offset
   END - qs.statement_start_offset)/2) + 1) AS statement_text, *
 from sys.dm_exec_requests qs
cross apply sys.dm_exec_sql_text(sql_handle) st
cross apply sys.dm_exec_query_plan(plan_handle)
 

Veritabanı dosyaları üzerinde kalan boş alanın takip edilmesi bir DBA için çok önemli bir iştir. Veritabanlarından birinin içindeki filegrouplarda boş datafile kalmadıysa ve otomatik büyüme "autogrowth" aktifleştirilmiş ise veritabanına ekstra alan tanımlanana kadarki süreçte birçok hata mesajı ile karşılaşacağınız neredeyse kesindir.

 

DBA'in veritabanı üzerinde kalan boş alanı monitör etmesinin birçok nedeni vardır. Öncelikle veritabanı üzerindeki verinin artması performansla direk ilişkilidir.  Bir başka neden ise boyut planlama olarak gösterilebilir. DBA veritabanı üzerindeki verinin boyutuna bakarak autogrowth değerinin büyüklüğünü önceden planlayabilir böylece birden çok autogrowth işlemi yerine bu işlemin 1 kerede yapılması ya da tam tersi gibi ihtiyaçlar karşılanmış olur.

CREATE PROCEDURE [dbo].[GetFileSpaceStats] (@RunLocal bit = 0)
AS
BEGIN 

/*
DECLARE @RunLocal bit
SET @RUnLocal = 1
*/
DECLARE @dbName sysname 

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE name = 'FileSpaceStats' AND type='U')
BEGIN
 CREATE TABLE [dbo].[FileSpaceStats]
 (
  Server_Name sysname NOT NULL,
  dbName sysname NOT NULL,
  Flag bit NULL,
  Fileid tinyint NULL,
  FileGroup sysname NULL,
  Total_Space decimal(20, 1) NULL,
  UsedSpace decimal(20, 1) NULL,
  FreeSpace decimal(20, 1) NULL,
  FreePct decimal(20, 3) NULL,
  Name varchar(250) NULL,
  FileName sysname NULL ,
  Report_Date datetime default getdate()
 )
 --ON PRIMARY 
END 

IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE name LIKE '#FileSpaceStats%')
BEGIN
 DROP TABLE #FileSpaceStats
END

CREATE TABLE #FileSpaceStats
(
 RowID int IDENTITY PRIMARY KEY,
 Server_Name sysname NOT NULL,
 dbName sysname NOT NULL,
 Flag bit NULL,
 Fileid tinyint NULL,
 FileGroup sysname NULL,
 Total_Space decimal(20, 1) NULL,
 UsedSpace decimal(20, 1) NULL,
 FreeSpace decimal(20, 1) NULL,
 FreePct decimal(20, 3) NULL,
 Name varchar(2500) NULL,
 FileName sysname NULL ,
 Report_Date datetime default getdate()
)

IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE name LIKE '#DataFileStats%')
BEGIN
 DROP TABLE #DataFileStats
END

CREATE TABLE #DataFileStats
(
 RowID int IDENTITY PRIMARY KEY,
 Flag bit default 0,
 Fileid tinyint,
 FileGroup tinyint,
 TotalExtents dec (20, 1),
 UsedExtents dec (20, 1),
 Name varchar(250),
 FileName sysname
) 

IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE name LIKE '#LogSpaceStats%')
BEGIN
 DROP TABLE #LogSpaceStats
END
CREATE TABLE #LogSpaceStats
(
 RowID int IDENTITY PRIMARY KEY,
 dbName sysname,
 Flag bit default 1,
 Totallogspace dec (20, 1),
 UsedLogSpace dec (20, 1),
 Status char(1)
) 

DECLARE @string sysname
DECLARE cur_dbName CURSOR FOR 

SELECT name
FROM master..sysdatabases

OPEN cur_dbName 

FETCH NEXT FROM cur_dbName into @dbName
WHILE @@FETCH_Status=0
BEGIN 

 DELETE #DataFileStats

 SET @string = 'USE [' + @dbName + '] DBCC SHOWFILESTATS WITH NO_INFOMSGS' 

 INSERT INTO #DataFileStats (Fileid, FileGroup, TotalExtents, UsedExtents, Name, FileName)
 EXEC (@string) 

 INSERT #FileSpaceStats (Server_Name, dbName, Flag, Fileid, FileGroup, Total_Space,
          UsedSpace, FreeSpace, FreePct, Name, FileName)

 SELECT @@SERVERNAME, @dbName, Flag, Fileid, FileGroup_Name(FileGroup), (TotalExtents*64/1024),
   (UsedExtents*64/1024), ((TotalExtents*64/1024)-(UsedExtents*64/1024)),
   (((TotalExtents*64/1024)-(UsedExtents*64/1024))*100/(TotalExtents*64/1024))/100,
   Name, FileName
 FROM #DataFileStats 

FETCH NEXT FROM cur_dbName into @dbName
END
CLOSE cur_dbName
DEALLOCATE cur_dbName 

INSERT #LogSpaceStats (dbName, Totallogspace, UsedLogSpace, Status)
EXEC ('DBCC sqlperf(logspace) WITH NO_INFOMSGS') 

INSERT #FileSpaceStats (Server_Name, dbName, Flag, Fileid, FileGroup, Total_Space,
     UsedSpace, FreeSpace, FreePct, Name, FileName)
SELECT @@SERVERNAME, dbName, Flag, 0, 'LOG', Totallogspace, (TotalLogSpace*(UsedLogSpace/100)),
  (TotalLogSpace-(TotalLogSpace*(UsedLogSpace/100))), (100-UsedLogSpace)/100, dbName+'_Log',
  dbName+'_Log.ldf'
FROM #LogSpaceStats 

INSERT dbo.FileSpaceStats
 (Server_Name, dbName, Flag, Fileid, FileGroup, Total_Space, UsedSpace,
  FreeSpace, FreePct, Name, FileName)
SELECT Server_Name, dbName, Flag, Fileid, FileGroup, Total_Space, UsedSpace,
  FreeSpace, FreePct, Name, FileName
FROM #FileSpaceStats

IF @RunLocal = 1
BEGIN
 SELECT * FROM #FileSpaceStats
END
ELSE
BEGIN
  DECLARE @Loop int
  DECLARE @Subject varchar(100)
  DECLARE @strMsg varchar(4000)

  SELECT @Subject = 'SQL Monitor Alert: ' + @@servername

  SELECT @Loop = min(RowID)
  FROM #FileSpaceStats
  WHERE FreePct <= .10

  WHILE @Loop IS NOT NULL
  BEGIN

   SELECT  @strMsg = convert(char(15),'Database:') + isnull(dbName, 'Unknown') + char(10) +
     convert(char(15),'FileGroup:') + isnull(FileGroup, 'Unknown') + char(10) +
     convert(char(15),'FileName:') + isnull(Name, 'Unknown') + char(10) +
     convert(char(15),'') + convert(varchar, convert(decimal(18,1), FreePct*100)) + '% boş yer bulunmaktadur.'+ char(10) +
     convert(char(15),'') + char(10) +
     convert(char(15),'EventTime:') + convert(varchar, getdate())
   FROM #FileSpaceStats
   WHERE RowID = @Loop

   EXEC dbo.SendEmailNotification @Subject, @strMsg

   SELECT @Loop = min(RowID)
   FROM #FileSpaceStats
   WHERE FreePct <= .10
    AND RowID > @Loop

  END

END

DROP TABLE #FileSpaceStats
DROP TABLE #DataFileStats
DROP TABLE #LogSpaceStats 

END 
 

Disk alanı SQL Server üzerinde birçok faktörden dolayı  çoğu zaman en değerli varlıktır. Depolama için Storage Area Network (SAN) Kullanan sunucularda ekstra depolama alanı için yapılacak genişlemeler  kolay olabilir ancak bu SAN üzerinde boş alanın olup olmamasına bağlıdır. Direct Attached Storage (DAS) kullanan sunucular üzerinde yapılacak genişlemeler çok daha zor olabilir.  Bu durumda sunucunun uzun süre down olması ve var olan disklerin daha genişleri ile değiştirilmesi ya da sunucuya harici bir disk eklenmesi gerekir,bunların hiçbiri genelde maliyeti düşük olan işlemler değildir ve doğru zamanda bu işlemlerin yapılmasını planlamak için DBA'in kalan disk alanını monitor edebilmesi çok önemli bir gereklilik olarak karşımıza çıkar.

 

İlk olarak kullanılabilecek yöntem xp_fixeddrives komutu. Herhangi bir parametre istemeyen bu komut çalıştırıldığında Mountpoint diskler haricinde harf ile atanan diskler hakkında bilgi alınabilir. Bu komut undocumented bir komut olduğundan ne zamana kadar destekleneceğinin bilinmediğini de unutmamak gerekli.

 

İkinci olarak SQL Server üzerinde kalan disk alanını belirlemek için COM FileSystemObject sınıfı kullanılarak işletim sistemine çağrılar yapılabilir. Aşağıdaki saklı yordam ile disk üzerindeki boş alan yüzde 15'in altına düştüğünde bilgilendirme yapılması öngörülmüştür. Aşağıdaki kodda değişiklik yaparak bu oranı değiştirebilir alacağınız uyarı mesajını kişiselleştirebilirsiniz.

CREATE PROCEDURE [dbo].[GetDiskSpaceStats] (@RunLocal bit = 0)
AS
BEGIN 

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE name = 'DiskSpaceStats' AND type='U')
BEGIN
    CREATE TABLE [dbo].[DiskSpaceStats]
    (
        DriveLetter        char(1),
        TotalSize        decimal(20,0),
        AvailableBytes    decimal(20,0),
        DriveType        char(10),
        PercentFree        decimal(18,3),
        Report_Date        datetime default getdate()
    )
    ON [PRIMARY]
END 

IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE name LIKE '#DiskSpace%')
DROP TABLE #DiskSpace
CREATE TABLE #DiskSpace
(
    RowID int Identity Primary Key,
    DriveLetter char(1),
    TotalSize decimal(20,0),
    AvailableBytes decimal(20,0),
    DriveType char(10),
    PercentFree decimal(18,3)
)

DECLARE @counter int
DECLARE @FSOobject int
DECLARE @RecordCount int
DECLARE @count int
DECLARE @string char(35)
DECLARE @DriveLetter char(1)
DECLARE @TotalSize char(50)
DECLARE @AvailableSpace char(50)
DECLARE @DriveType char(10)
DECLARE @error int
DECLARE @hr int
DECLARE @src varchar(255), @desc varchar(255)
DECLARE @ServerName sysname

SET @ServerName = @@ServerName
SET @count=0
SET @counter=67
SET @error=0

EXEC @hr = sp_OACreate 'Scripting.FileSystemObject', @FSOobject OUT

IF @hr <> 0
    BEGIN
        EXEC sp_OAGetErrorInfo @FSOobject, @src OUT, @desc OUT
        PRINT @desc
        RETURN
    END

WHILE @counter < 91 OR @error <3
    BEGIN
        SET @String='Drives.item("'+char(@counter)+'").DriveLetter'
        EXEC @HR = sp_OAGetProperty @FSOobject, @String, @DriveLetter OUT
        IF @HR <> 0
            BEGIN
                EXEC sp_OAGetErrorInfo @FSOobject, @src OUT, @desc OUT
                SELECT @counter=@counter+1
                SELECT @error=@error +1
                GOTO ErrorPoint
            END

        SET @String='Drives.item("'+char(@counter)+'").TotalSize'
        EXEC @HR = sp_OAGetProperty @FSOobject, @string, @TotalSize OUT
        IF @HR <> 0
            BEGIN
                EXEC sp_OAGetErrorInfo @FSOobject, @src OUT, @desc OUT
                SELECT @counter=@counter+100
                SELECT @error=1
            END 

        SET @String='Drives.item("'+char(@counter)+'").AvailableSpace'
        EXEC @HR = sp_OAGetProperty @FSOobject, @string, @AvailableSpace OUT
        IF @HR <> 0
            BEGIN
                EXEC sp_OAGetErrorInfo @FSOobject, @src OUT, @desc OUT
                PRINT @desc
                RETURN
            END

        SET @String='Drives.item("'+char(@counter)+'").DriveType'
        EXEC @HR = sp_OAGetProperty @FSOobject, @String, @DriveType OUT
        IF @HR <> 0
            BEGIN
                EXEC sp_OAGetErrorInfo @FSOobject, @src OUT, @desc OUT
                PRINT @desc
                RETURN
            END

        IF @Error < 3
            BEGIN
                INSERT INTO #DiskSpace (DriveLetter, TotalSize, AvailableBytes, DriveType, PercentFree)
                VALUES (@DriveLetter, @TotalSize, @AvailableSpace, @DriveType, (convert(decimal(20,0), @AvailableSpace)/convert(decimal(20,0), @TotalSize)))
            END

        SELECT @counter=@counter+1
    END

ErrorPoint:

INSERT INTO [dbo].[DiskSpaceStats] (DriveLetter, TotalSize, AvailableBytes, DriveType, PercentFree)
SELECT DriveLetter, TotalSize, AvailableBytes, DriveType, PercentFree
FROM #DiskSpace

    EXEC @hr = sp_OADestroy @FSOobject
    IF @hr <> 0
        BEGIN
            EXEC sp_OAGetErrorInfo @FSOobject
        RETURN
    END

IF @RunLocal = 1
BEGIN
 SELECT * FROM #DiskSpace
END
ELSE
BEGIN

        DECLARE @Loop int
        DECLARE @Subject varchar(100)
        DECLARE @strMsg varchar(4000)

        SELECT @Subject = 'SQL Monitor Alert: ' + @@servername

        SELECT @Loop = min(RowID)
        FROM #DiskSpace
        WHERE PercentFree <= .15

        WHILE @Loop IS NOT NULL
        BEGIN

            SELECT     @strMsg = convert(char(15),'Drive:') + isnull(DriveLetter, 'Unknown') + char(10) +
                    convert(char(15),'') + convert(varchar, convert(decimal(18,1), PercentFree*100)) + '% free space remaining.'+ char(10) +
                    convert(char(15),'') + char(10) +
                    convert(char(15),'EventTime:') + convert(varchar, getdate())
            FROM #DiskSpace
            WHERE RowID = @Loop

            EXEC dbo.SendEmailNotification @Subject, @strMsg

            SELECT @Loop = min(RowID)
            FROM #DiskSpace
            WHERE PercentFree <= .15
             AND RowID > @Loop

        END

END

DROP TABLE #DiskSpace

END
 

 

Çoğu zaman hangi prosedürlerin ya da sorguların Server üzerine en fazla yük bindirdiği bilinmek istenir. Bu yük bazen giriş/çıkış işlemlerinin yükü bazen işlem süresi ile ölçülür.

 

Aşağıdaki örnekte 10 prosedürün bazı etkenler baz alınarak yapılan karşılaştırması gösterilmiştir.

 

SQL Server 2005/2008 Çözümü :

 

 

SELECT TOP 10
  ProcedureName  = t.text,
  ExecutionCount  = s.execution_count,
  AvgExecutionTime = isnull( s.total_elapsed_time / s.execution_count, 0 ),
  AvgWorkerTime  = s.total_worker_time / s.execution_count,
  TotalWorkerTime = s.total_worker_time,
  MaxLogicalReads = s.max_logical_reads,
  MaxLogicalWrites = s.max_logical_writes,
  CreationDateTime = s.creation_time,
  CallsPerSecond  = isnull( s.execution_count / datediff( second, s.creation_time, getdate()), 0 )
FROM sys.dm_exec_query_stats s
  CROSS APPLY sys.dm_exec_sql_text( s.sql_handle ) t
-- WHERE ...
ORDER BY
  s.total_elapsed_time DESC

 

Alınan çıktı :

 

 

ProcedureName

ExecutionCount

AvgExecutionTime

AvgWorkerTime

TotalWorkerTime

MaxLogicalReads

MaxLogicalWrites

CreationDateTime

CallsPerSecond

Exec Proc1

1

3723204

3596939

3596939

36249

112

2008-03-25 00:04:15.950

0

Exec Proc2

1

2512181

2389573

2389573

703

0

2008-03-24 23:59:15.980

0

Exec Proc3

1

1080008

971041

971041

443

0

2008-03-25 00:16:07.820

0

Exec Proc4

1

1032135

935483

935483

223

0

2008-03-25 00:13:55.193

0

Exec Proc5

1

955338

912818

912818

223

0

2008-03-25 00:15:06.617

0

Exec Proc6

1

946446

906498

906498

346

0

2008-03-25 00:15:33.227

0

Exec Proc7

1

635835

634566

634566

561

0

2008-03-24 23:22:00.280

0

Exec Proc8

1

481766

475023

475023

36202

105

2008-03-25 00:13:55.180

0

Exec Proc9

1

349026

343143

343143

36202

105

2008-03-25 00:15:06.600

0

Exec Proc10

1

346581

337336

337336

36202

105

2008-03-25 00:15:33.227

0

 

 

 

 

Bir yedek alma işlemi yapıldığında SQL Server  msdb.dbo.backupfile, msdb.dbo.backupmediafamily, msdb.dbo.backupmediaset ve msdb.dbo.backupset tablolarını günceller.

 

Bu tabloları kullanarak veritabanlarınız hakkında bilgi edinebilirsiniz. Aşağıdaki sorgu ile veritabanı ismi en son alınan yedek tarihi ve yedeği kimin aldığı gibi bilgiler listelenmektedir.

 

SELECT
T1.Name as DatabaseName,
COALESCE(Convert(varchar(12), MAX(T2.backup_finish_date), 101),'Not Yet Taken') as LastBackUpTaken,
COALESCE(Convert(varchar(12), MAX(T2.user_name), 101),'NA') as UserName
FROM sys.sysdatabases T1 LEFT OUTER JOIN msdb.dbo.backupset T2
ON T2.database_name = T1.name
GROUP BY T1.Name
ORDER BY T1.Name

 
SET NOCOUNT ON

DECLARE
  @dbName   varchar(80),
  @ServerName varchar(20)

SELECT @ServerName = @@servername

DECLARE dbCursor CURSOR FOR
  SELECT name
  FROM master.dbo.sysdatabases
  WHERE name NOT IN ( 'model', 'master', 'msdb', 'tempdb', 'distribution', 'repldata' )

OPEN dbCursor 

FETCH NEXT FROM dbCursor INTO @dbName

IF ( @@FETCH_STATUS <> 0 )
  PRINT 'Kullanıcı Tanımlı Veritabanı Bulunamadı'

WHILE ( @@FETCH_STATUS = 0 )
  BEGIN
   DECLARE @SQLStr varchar(8000)
   SET @SQLStr =
    'DECLARE
      @SPIDStr  varchar(8000),
      @ConnKilled smallint
     SELECT
      @ConnKilled = 0
      @SPIDStr  = ''''
     SELECT @SPIDStr = coalesce( @SPIDStr, '', '' ) + ''KILL '' + convert( varchar, spid ) + ''; ''
     FROM master.dbo.sysprocesses
     WHERE dbid = db_id( ''' + @dbName + ''' )
     IF LEN( @SPIDStr ) > 0
      BEGIN
        EXECUTE( @SPIDStr )
        SELECT @ConnKilled = COUNT(1)
        FROM master..sysprocesses
        WHERE dbid = db_id( ''' + @dbName + ''' )
      END' + char(10) + ';' + char(10) +
    'EXECUTE sp_detach_db ' + @dbName
   EXECUTE ( @SQLStr )
   PRINT upper( @dbName ) + ' Veritabanının Detach işlemi sonlandırıldı.'
   PRINT ''
   FETCH NEXT FROM dbCursor INTO @dbName
  END

CLOSE dbCursor
DEALLOCATE dbCursor

PRINT ' '
PRINT upper( @ServerName ) + ' -->Tüm Kullanıcı tanımlı Veritabanları Kaldırıldı'
 

Her kategori/grup için çok satırlı verilerin bulunduğu ortamlarda örneğin "her kategoriden en pahalı 2 ürünü" listelemek benzeri işlemlerin yapılması istenebilir. Örnek tablo ve istenen çıktı :

 

 

 

 

RowID

Category

ID

Description

Price

1

Pot

A1

Small Saucepan

21.50

2

Pot

A2

1 Qt Saucepan

29.95

3

Pot

A3

1.5 Qt Saucepan

33.95

4

Pot

A4

Double Boiler

39.50

5

Pot

A5

Stewpot

49.50

6

Pot

A6

Pressure Cooker

79.95

7

Pan

B1

8" Pie

6.95

8

Pan

B2

8" Sq Cake

7.50

9

Pan

B3

Bundt Cake

12.50

10

Pan

B4

9×12 Brownie

7.95

11

Bowl

C1

Lg Mixing

27.50

12

Bowl

C2

Sm Mixing

17.50

13

Tools

T1

14" Spatula

9.95

 

 

 

RowID

Category

ID

Description

Price

11

Bowl

C1

Lg Mixing

27.50

12

Bowl

C2

Sm Mixing

17.50

9

Pan

B3

Bundt Cake

12.50

10

Pan

B4

9×12 Brownie

7.95

6

Pot

A6

Pressure Cooker

79.95

5

Pot

A5

Stewpot

49.50

13

Tools

T1

14" Spatula

9.95

 

 

Önce üzerinde çalışacağımız verileri oluşturalım :

SET NOCOUNT ON

DECLARE @MyTable table
  ( RowID     int  IDENTITY,
   Category   varchar(5),
   [ID]     varchar(5),
   [Description] varchar(25),
   Price     decimal(10,2)
  )

INSERT INTO @MyTable VALUES ( 'Pot', 'A1', 'Small Saucepan', 21.50 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A2', '1 Qt Saucepan', 29.95 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A3', '1.5 Qt Saucepan', 33.95 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A4', 'Double Boiler', 39.50 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A5', 'Stewpot', 49.50 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A6', 'Pressure Cooker', 79.95 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B1', '8"" Pie', 6.95 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B2', '8"" Sq Cake', 7.50 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B3', 'Bundt Cake', 12.50 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B4', '9x12 Brownie', 7.95 )
INSERT INTO @MyTable VALUES ( 'Bowl', 'C1', 'Lg Mixing', 27.50 )
INSERT INTO @MyTable VALUES ( 'Bowl', 'C2', 'Sm Mixing', 17.50 )
INSERT INTO @MyTable VALUES ( 'Tools', 'T1', '14"" Spatula', 9.95 )

SQL Server 2005/2008 Çözümü :

 

SELECT
  RowID,
  Category,
  [ID],
  [Description],
  Price
FROM (SELECT
     ROW_NUMBER() OVER ( PARTITION BY Category ORDER BY Price DESC ) AS 'RowNumber',
     RowID,
     Category,
     [ID],
     [Description],
     Price
   FROM @MyTable
   ) dt
WHERE RowNumber <= 2

-- Sonuçlar
RowID Category ID Description   Price
11  Bowl   C1 Lg Mixing    27.50
12  Bowl   C2 Sm Mixing    17.50
9   Pan    B3 Bundt Cake   12.50
10  Pan    B4 9x12 Brownie  7.95
6   Pot    A6 Pressure Cooker 79.95
5   Pot    A5 Stewpot     49.50
13  Tools   T1 14" Spatula   9.95

SQL Server 2000 Çözümü

 

SELECT DISTINCT
  RowID,
  Category,
  [ID],
  [Description],
  Price
FROM @MyTable t1
WHERE RowID IN (SELECT TOP 2
          RowID
        FROM @MyTable t2
        WHERE t2.Category = t1.Category
        ORDER BY Price DESC
        )
ORDER BY
  Category,
  Price DESC

-- Sonuçlar
RowID Category ID Description   Price
11  Bowl   C1 Lg Mixing    27.50
12  Bowl   C2 Sm Mixing    17.50
9   Pan    B3 Bundt Cake   12.50
10  Pan    B4 9x12 Brownie  7.95
6   Pot    A6 Pressure Cooker 79.95
5   Pot    A5 Stewpot     49.50
13  Tools   T1 14" Spatula   9.95

 

 

Büyük veritabanları ile çalışıldığında verilerin uygulamaya getirilmesi zaman açısından sorun oluşturabilir.  Verinin görüntülenmesinde en sıklıkla kullanılan DataGridView/GridView kontrolleri ile sayfalama yapıldığını düşünelim bir kerede kullanıcıya 10 satır görüntülenecek ise tüm verinin getirilmesi yerine 10'ar 10'ar getirilmesini sağlayacak bir saklı yordam yazarak bu işlem hızlandırılabilir.

 

SQL Server 2005/2008 için ROW_NUMBER() fonksiyonunu kullanan,SQL Server 2000 için ise bir tablo değişkeninin kullanıldığı T-SQL çözümünü gösteren aşağıdaki örnekleri inceleyelim :

 

 

SQL Server 2005/2008 Çözümü :

 

DECLARE     @Start datetime,
    @End datetime

SELECT    @Start = 11,
    @End = 20

;WITH ObjectsTABLE AS
(
 SELECT ROW_NUMBER() OVER (ORDER BY name) AS Row,
        convert(varchar(30), name) as objName,
        crDate
 FROM sysobjects
)

SELECT    objName, CrDate
FROM ObjectsTable
WHERE Row >= @Start AND Row <= @End

/* Sonuçlar
objName            CrDate
------------------------------ -----------------------
assembly_modules        2007-02-10 00:23:25.353
assembly_references      2007-02-10 00:23:29.183
assembly_types         2007-02-10 00:23:27.870
asymmetric_keys        2007-02-10 00:23:52.917
backup_devices         2007-02-10 00:23:41.870
certificates          2007-02-10 00:23:52.260
check_constraints       2007-02-10 00:23:20.760
CHECK_CONSTRAINTS       2007-02-10 00:27:23.027
COLUMN_DOMAIN_USAGE      2007-02-10 00:27:21.060
COLUMN_PRIVILEGES       2007-02-10 00:27:21.387
*/

 

SQL Server 2000 Çözümü :

 

DECLARE     @Start datetime,
    @End datetime

SELECT    @Start = 11,
    @End = 20

DECLARE @PagingTable TABLE
(Row int identity primary key,
 objName varchar(30),
 crDate datetime)

INSERT INTO @PagingTable (objName, crDate)
SELECT    convert(varchar(30), name) as objName,
        crDate
FROM sysobjects
ORDER BY Name

SELECT    objName, CrDate
FROM @PagingTable
WHERE Row >= @Start AND Row <= @End

/* Sonuçlar
objName            CrDate
------------------------------ -----------------------
assembly_modules        2007-02-10 00:23:25.353
assembly_references      2007-02-10 00:23:29.183
assembly_types         2007-02-10 00:23:27.870
asymmetric_keys        2007-02-10 00:23:52.917
backup_devices         2007-02-10 00:23:41.870
certificates          2007-02-10 00:23:52.260
check_constraints       2007-02-10 00:23:20.760
CHECK_CONSTRAINTS       2007-02-10 00:27:23.027
COLUMN_DOMAIN_USAGE      2007-02-10 00:27:21.060
COLUMN_PRIVILEGES       2007-02-10 00:27:21.387
*/

© 2011 Emre GÜNERTÜRK @2011 Suffusion theme by Sayontan Sinha