SQL Server 2012’de Sorgu Sayfalama (Query Pagination)
Merhaba millet!
Hemen konuya giriyorum; Web uygulaması geliştiren bütün yazılım geliştiricilerinin mutlaka karşılaşmış olduğu bir sorun vardır: Sayfalama. Hemen örneklendirelim, bir e-ticaret sitesinin web sayfasında ürünleri listeleyeceksiniz ve yaklaşık 150 ürün var. Hepsini bir sayfada göstermektense elbette sayfalama işlemi yapacaksınız. Ama bir dakika! Nerede sayfalayacaksınız? Tüm datayı belleğe (RAM) atıp, kod ile mi sayfalayacaksınız yoksa veritabanında mı sayfalama işlemini gerçekleştireceksiniz? Düşündünüz, taşındınız ve sonunda sayfalamayı veritabanında yapmaya karar verdiniz. Tebrikler! Doğru karar! 150 satır (daha fazla da olabilirdi J) datayı bir kerede belleğe atmaktansa, sayfa numarasına göre veritabanından çekmek çok daha hızlı!
Peki, bunu nasıl yapacaksınız? Sayfa numarası ve sayfada toplam kaç satır datanın gösterileceği bilgisini parametre olarak alan bir prosedür yazsak nasıl olur? Basit bir formülle bu işin üstesinden gelebiliriz sanırım. Ha unutmadan; ben tabii ki Northwind veritabanını kullandım.
CREATE PROC UrunSirala
(
@SayfaNo int,
@SayfabasinaSayi int
)
AS
BEGIN
WITH Sirali AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY ProductID) AS SatirNo,
ProductID,
ProductName,
UnitPrice
FROM Products
)
SELECT ProductID,ProductName,UnitPrice FROM Sirali
WHERE SatirNo BETWEEN (((@SayfaNo – 1) * @SayfabasinaSayi) +1)
AND (@SayfaNo * @SayfabasinaSayi)
ORDER BY ProductID
END
Gördüğünüz gibi, öncelikle WITH ile “sıralı” isminde bir resultset oluşturdum. Bu resultset’in özelliği, satır numaralarını da içerisinde barındırıyor olması. Ardından ikinci bir sorguyla, sirali resultsetini filtreledim. Sonuç?
UrunSirala 1,5
Şimdi sürprize hazır olun! Efendim, yukarıdaki çözümümüz SQL Server 2012 ile gelen yeni bir yaklaşımla daha pratik bir hale geliyor.
CREATE PROC UrunSirala_Yeni
(
@SayfaNo int,
@SayfabasinaSayi int
)
AS
BEGIN
SELECT ProductID,ProductName,UnitPrice
FROM Products
ORDER BY ProductID
OFFSET ((@SayfaNo –1) * @SayfabasinaSayi) ROWS
FETCH NEXT @SayfabasinaSayi ROWS ONLY;
END
Hemen çalıştırıyoruz:
UrunSirala_Yeni 1,6
Üstelik çok daha performanslı! İnanmazsanız, Execution Plan üzerinden bakın 🙂
Haydi kalın sağlıcakla!
ellerinize sağlık, büyük veriyle çalışanlar için güzel bir çözüm olmuş hocam
hocam bende 2012 kullaniyorum ama bende bu kodlar calismiyor asagidaki gibi bir hata gelmekte.
Msg 102, Level 15, State 1, Procedure UrunSirala_Yeni, Line 21
Incorrect syntax near ‘OFFSET’.
Msg 153, Level 15, State 2, Procedure UrunSirala_Yeni, Line 23
Invalid usage of the option NEXT in the FETCH statement.