SQL Depolanan Prosedürler içinde Dinamik Sıralama


126

Bu, geçmişte araştırmak için saatler harcadığım bir konu. Bana öyle geliyor ki, modern RDBMS çözümleri tarafından ele alınması gereken bir şey var, ancak henüz veritabanı arka uçlu herhangi bir Web veya Windows uygulamasında inanılmaz derecede yaygın bir ihtiyaç olarak gördüğüm şeyi gerçekten karşılayan hiçbir şey bulamadım.

Dinamik sıralamadan bahsediyorum. Benim fantezi dünyamda, şöyle bir şey kadar basit olmalı:

ORDER BY @sortCol1, @sortCol2

Bu, yeni başlayan SQL ve Depolanan Prosedür geliştiricileri tarafından İnternet'in her yerinde forumlarda verilen kanonik örnektir . "Bu neden mümkün değil?" onlar sorar. Değişmez bir şekilde, birileri sonunda onlara depolanmış yordamların, genel olarak yürütme planlarının derlenmiş doğası ve bir parametreyi doğrudan bir ORDER BYmaddeye koymanın mümkün olmadığı her türden diğer nedenler hakkında ders vermek için gelir .


Bazılarınızın halihazırda ne düşündüğünü biliyorum: "Öyleyse, müşteri sıralamayı yapsın." Doğal olarak, bu işi veritabanınızdan kaldırır. Yine de bizim durumumuzda, veritabanı sunucularımız zamanın% 99'unda ter bile atmıyor ve henüz çok çekirdekli değiller veya her 6 ayda bir sistem mimarisinde yapılan diğer sayısız iyileştirmelerden hiçbiri. Bu nedenle tek başına, veritabanlarımızın sıralamayı ele alması sorun olmaz. Ek olarak, veritabanları çoksıralama konusunda iyi. Bunun için optimize edilmişlerdir ve doğru yapmak için yılları olmuştur, bunu yapmak için kullanılan dil inanılmaz derecede esnek, sezgisel ve basittir ve hepsinden önemlisi, yeni başlayan herhangi bir SQL yazarı bunu nasıl yapacağını bilir ve daha da önemlisi onu nasıl düzenleyeceğini bilir, değişiklikler yapın, bakım yapın, vb. Veritabanlarınız vergilendirilmekten uzaksa ve yalnızca geliştirme süresini basitleştirmek (ve kısaltmak!) istiyorsanız, bu bariz bir seçim gibi görünüyor.

Sonra web sorunu var. HTML tablolarının istemci tarafında sıralanmasını sağlayacak JavaScript ile oynadım, ancak bunlar kaçınılmaz olarak ihtiyaçlarım için yeterince esnek değiller ve yine, veritabanlarım fazla vergilendirilmediğinden ve gerçekten kolayca sıralama yapabildiğinden , ben Kendi JavaScript sıralayıcımı yeniden yazmak veya almak için gereken zamanı haklı çıkarmada güçlük çekiyorum. Aynı durum genellikle sunucu tarafında sıralama için de geçerlidir, ancak muhtemelen JavaScript'e göre daha çok tercih edilmektedir. DataSets'in ek yükünü özellikle beğenen biri değilim, bu yüzden beni dava et.

Ancak bu, mümkün olmadığı veya daha doğrusu kolay olmadığı noktasını geri getiriyor. Önceki sistemlerle, dinamik sıralama elde etmenin inanılmaz derecede hacklenmiş bir yolunu yaptım. Güzel, sezgisel, basit veya esnek değildi ve yeni başlayan bir SQL yazarı saniyeler içinde kaybolurdu. Zaten bu bir "çözüm" değil, bir "karmaşıklık" olarak görünüyor.


Aşağıdaki örnekler, herhangi bir tür en iyi uygulamayı veya iyi kodlama stilini veya herhangi bir şeyi ortaya çıkarmayı amaçlamaz veya bir T-SQL programcısı olarak yeteneklerimi göstermez. Onlar oldukları gibi ve kafa karıştırıcı, kötü formda ve sadece basit bir hack olduklarını tamamen itiraf ediyorum.

Depolanmış bir prosedüre parametre olarak bir tamsayı değeri iletiriz (parametreyi sadece "sırala" diyelim) ve bundan bir grup başka değişken belirleriz. Örneğin ... sıralamanın 1 (veya varsayılan) olduğunu varsayalım:

DECLARE @sortCol1 AS varchar(20)
DECLARE @sortCol2 AS varchar(20)
DECLARE @dir1 AS varchar(20)
DECLARE @dir2 AS varchar(20)
DECLARE @col1 AS varchar(20)
DECLARE @col2 AS varchar(20)

SET @col1 = 'storagedatetime';
SET @col2 = 'vehicleid';

IF @sort = 1                -- Default sort.
BEGIN
    SET @sortCol1 = @col1;
    SET @dir1 = 'asc';
    SET @sortCol2 = @col2;
    SET @dir2 = 'asc';
END
ELSE IF @sort = 2           -- Reversed order default sort.
BEGIN
    SET @sortCol1 = @col1;
    SET @dir1 = 'desc';
    SET @sortCol2 = @col2;
    SET @dir2 = 'desc';
END

Diğer sütunları tanımlamak için daha fazla @colX değişkeni bildirmişsem, "sırala" değerine göre sıralama yapmak için sütunlarla gerçekten yaratıcı olabileceğimi zaten görebilirsiniz ... kullanmak için, genellikle aşağıdaki gibi görünür inanılmaz derecede dağınık madde:

ORDER BY
    CASE @dir1
        WHEN 'desc' THEN
            CASE @sortCol1
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END DESC,
    CASE @dir1
        WHEN 'asc' THEN
            CASE @sortCol1
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END,
    CASE @dir2
        WHEN 'desc' THEN
            CASE @sortCol2
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END DESC,
    CASE @dir2
        WHEN 'asc' THEN
            CASE @sortCol2
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END

Açıkçası bu çok sade bir örnek. Gerçek şeyler, sıralamayı desteklemek için genellikle dört veya beş sütuna sahip olduğumuz için, her biri buna ek olarak sıralamak için olası ikincil veya hatta üçüncü bir sütun (örneğin, azalan tarih sonra ikinci olarak ad artan şekilde sıralanır) ve her birini destekleyen iki sütun vaka sayısını etkili bir şekilde ikiye katlayan yönlü sıralama. Evet ... çok çabuk kıllı oluyor.

Buradaki fikir, araç kimliğinin depolama süresinden önce sıralanacağı şekilde sıralama durumlarının "kolayca" değiştirilebilmesidir ... ancak sözde esneklik, en azından bu basit örnekte, gerçekten burada biter. Esasen, bir testi geçemeyen her durum (çünkü bizim sıralama yöntemimiz bu sefer onun için geçerli değildir) bir NULL değeri verir. Ve böylece aşağıdaki gibi işleyen bir cümle ile sonuçlanırsınız:

ORDER BY NULL DESC, NULL, [storagedatetime] DESC, blah blah

Kaptın bu işi. Çalışır çünkü SQL Server, cümleciklere göre sırayla boş değerleri yok sayar. Temel SQL çalışma bilgisine sahip herkesin muhtemelen görebileceği gibi, bunu sürdürmek inanılmaz derecede zordur. Herhangi birinizi kaybedersem, kendinizi kötü hissetmeyin. Çalışması uzun zamanımızı aldı ve onu düzenlemeye veya buna benzer yenilerini oluşturmaya çalışırken hala kafamız karışıyor. Neyse ki sık sık değişmesi gerekmiyor, aksi takdirde çabucak "zahmete değmez" hale gelirdi.

Yine de işe yaradı .


O zaman sorum şu: daha iyi bir yol var mı?

Depolanan Prosedür dışındaki çözümlerde sorun yok, çünkü bunun gidecek yol olmayabileceğinin farkındayım. Tercihen, herhangi birinin Depolanan Prosedür içinde bunu daha iyi yapıp yapamayacağını bilmek isterim, ancak değilse, kullanıcının ASP.NET ile veri tablolarını dinamik olarak (çift yönlü olarak da) sıralamasına izin vermeyi nasıl başaracaksınız?

Ve bu kadar uzun bir soruyu okuduğunuz (veya en azından gözden geçirdiğiniz) için teşekkür ederiz!

Not: Dinamik sıralamayı, dinamik filtrelemeyi / sütunların metin aramasını, ROWNUMBER () OVER aracılığıyla sayfalandırmayı destekleyen VE deneyin ... hatalarda işlem geri alma ile yakala ... "Devasa boyutta" onları tanımlamaya bile başlamaz.


Güncelleme:

  • Dinamik SQL'den kaçınmak istiyorum . Bir dizeyi birlikte ayrıştırmak ve üzerinde bir EXEC çalıştırmak, ilk etapta bir saklı yordama sahip olma amacının çoğunu ortadan kaldırır. Bazen böyle bir şeyi yapmanın eksilerinin buna değip değmeyeceğini merak ediyorum, en azından bu özel dinamik sıralama durumlarında. Yine de, böyle dinamik SQL dizeleri yaptığımda her zaman kendimi kirli hissediyorum - sanki hala Klasik ASP dünyasında yaşıyormuşum gibi.
  • Depolanan prosedürleri ilk etapta istememizin birçok nedeni güvenlik içindir . Güvenlik endişeleri için arama yapmıyorum, sadece çözüm öneriyorum. SQL Server 2005 ile ayrı saklı yordamlarda şema düzeyinde izinler (gerekirse kullanıcı bazında) ayarlayabilir ve ardından tablolara yönelik herhangi bir sorguyu doğrudan reddedebiliriz. Bu yaklaşımın artılarını ve eksilerini eleştirmek belki başka bir soru için olabilir, ama yine de bu benim kararım değil. Ben sadece baş kod maymuyum. :)


Dinamik SQL, FAR'ın üstün yoludur ... IF [ve bu büyük bir EĞER] ..Veri Erişim Katmanınız katıdır ve dinamik SQL'iniz, mükemmel biçimde ifade edilen RDBMS kuralları ile katı bir şekilde programlanmış bir sistem tarafından oluşturulur. Algoritmik
Olarak Tasarlanmış

Yanıtlar:


97

Evet, bu bir acı ve bunu yapma şeklin benim yaptığıma benziyor:

order by
case when @SortExpr = 'CustomerName' and @SortDir = 'ASC' 
    then CustomerName end asc, 
case when @SortExpr = 'CustomerName' and @SortDir = 'DESC' 
    then CustomerName end desc,
...

Bu benim için koddan dinamik SQL oluşturmaktan çok daha iyi, bu da DBA'lar için ölçeklenebilirlik ve bakım kabusuna dönüşüyor.

Ne kodundan yapmak çağrı refactor ve ben en azından değerlerini doldurma orada çok sayıda tekrar zorunda kalmamak sıralama @SortExprve @SortDir.

SQL söz konusu olduğunda, farklı depolanmış prosedürler arasında tasarımı ve biçimlendirmeyi aynı tutun, böylece değişiklik yapmak için girdiğinizde en azından düzgün ve tanınabilir.


1
Kesinlikle. Amacım, 5000 varchar dizgesinde EXEC komutu yapmaktan kaçınmaktı. Şema düzeyinde izinleri ayarlayabildiğimizden, yaptığımız her şey yalnızca ek güvenlik için saklı prosedürler aracılığıyla yapılmalıdır. Ölçeklenebilirlik ve performans kazanımları bizim durumumuzda sadece bir artı.
Sean Hanley

1
{Güvenlik, ölçeklenebilirlik, performans} için sürdürülebilirlik ekleyin. DB'nize karşı dinamik SQL çalışan 3 veya 4 uygulamanız olduğunda, mahvolursunuz, özellikle uygulamalar yaşlandıkça ve geliştiriciler ilerledikçe hiçbir şeyi değiştiremezsiniz. Yürütme ve dinamik sql kötüdür.
Eric Z Beard

İşte bu kadar --- ben buraya gelmeden çok önce, hala çalışan tüm Klasik ASP web uygulamaları ve hala dolaşımda olan birçok Access VB uygulaması için zaten yapıyoruz. Herhangi bir bakım yapmam gerektiğinde, göze batan hataları düzeltmek için seğiriyorum ve dürtüleri geri almam gerekiyor.
Sean Hanley

1
Bu aynı zamanda yaptığım şeydir, ancak yönü SortExpr'e kodlamam dışında: SİPARİŞ VERİNCE sort = 'FirstName' SONRA AD SON ASC, CASE WHEN sort = '-FirstName' THEN FirstName END DESC
Michael Bray

Bu, hem DBA'lar hem de yazılım mühendisleri için kabus. Dolayısıyla, bilgi şemanıza dayalı olarak ifade edici SQL ifadeleri üreten dinamik ancak katı sistemlere sahip olmak yerine, bu iğrenç kodlanmış anlamsız sözlere sahipsiniz. En iyisi kötü programlama.
hajikelist

23

Bu yaklaşım, sıralanabilir sütunların sırasıyla iki kez kopyalanmasını engeller ve biraz daha okunaklı bir IMO'dur:

SELECT
  s.*
FROM
  (SELECT
    CASE @SortCol1
      WHEN 'Foo' THEN t.Foo
      WHEN 'Bar' THEN t.Bar
      ELSE null
    END as SortCol1,
    CASE @SortCol2
      WHEN 'Foo' THEN t.Foo
      WHEN 'Bar' THEN t.Bar
      ELSE null
    END as SortCol2,
    t.*
  FROM
    MyTable t) as s
ORDER BY
  CASE WHEN @dir1 = 'ASC'  THEN SortCol1 END ASC,
  CASE WHEN @dir1 = 'DESC' THEN SortCol1 END DESC,
  CASE WHEN @dir2 = 'ASC'  THEN SortCol2 END ASC,
  CASE WHEN @dir2 = 'DESC' THEN SortCol2 END DESC

Bu iyi bir cevap gibi görünüyordu, ancak sıralanabilir sütunlar farklı veri türlerine sahip olduğunda işe yaramıyor gibi görünüyor
SlimSim


6

Uygulamalarım bunu çok yapıyor ancak hepsi dinamik olarak SQL'i oluşturuyor. Ancak, saklı yordamları ele aldığımda şunu yapıyorum:

  1. Depolanan yordamı, değerlerinizi içeren bir tablo döndüren bir işlev yapın - sıralama yok.
  2. Ardından uygulama kodunuzda bir yapın, select * from dbo.fn_myData() where ... order by ...böylece orada sıralama düzenini dinamik olarak belirtebilirsiniz.

O zaman en azından dinamik kısım uygulamanızda, ancak veritabanı hala işin zor kısmını yapıyor.


1
Dinamik SQL ve saklı yordamları birlikte kullanmak arasında şimdiye kadar gördüğüm en iyi uzlaşma muhtemelen budur. Bunu sevdim. Bazen benzer bir yaklaşım deneyebilirim, ancak böyle bir değişiklik, devam eden mevcut projelerimizin herhangi birinde engelleyici olacaktır.
Sean Hanley

1
Aynı şeyi, veri döndüren tabular işlev yerine yerel bir tablo değişkeni kullanarak da elde edebilirsiniz. Bazı hata ayıklama bilgilerinin çıktısını alabileceğiniz için yerel tabloları işlevlerden daha esnek buluyorum.
Sanjay Zalke

5

Belirli işler için dinamik SQL'den kaçınmak için kullandığım bir saklı yordam tekniği (hack?), Benzersiz bir sıralama sütununa sahip olmaktır. yani,

SELECT
   name_last,
   name_first,
   CASE @sortCol WHEN 'name_last' THEN [name_last] ELSE 0 END as mySort
FROM
   table
ORDER BY 
    mySort

Bu, kolayca gönderilebilir - mySort sütununuzdaki alanları birleştirebilir, sıralamayı matematik veya tarih işlevleriyle tersine çevirebilirsiniz, vb.

Tercihen, benim için sıralamayı Sql-Server'dan aldıktan SONRA yapmak için asp.net kılavuz görünümlerimi veya diğer nesneleri yerleşik sıralama ile kullanıyorum. Veya yerleşik olmasa bile - örneğin, asp.net'te veri tabloları vb.


4

Bunu hacklemenin birkaç farklı yolu var.

Ön şartlar:

  1. Sp'de yalnızca bir SELECT ifadesi
  2. Herhangi bir sıralamayı bırakın (veya bir varsayılanınız olsun)

Ardından geçici bir tabloya ekleyin:

create table #temp ( your columns )

insert #temp
exec foobar

select * from #temp order by whatever

Yöntem # 2: kendisine bağlı bir sunucu kurun, ardından openquery kullanarak bundan seçim yapın: http://www.sommarskog.se/share_data.html#OPENQUERY


4

Sunucunuzda çok sayıda yedek döngü olduğundan üçüncü bir seçenek olabilir - sıralamayı geçici bir tablo aracılığıyla yapmak için yardımcı bir prosedür kullanın. Gibi bir şey

create procedure uspCallAndSort
(
    @sql varchar(2048),        --exec dbo.uspSomeProcedure arg1,'arg2',etc.
    @sortClause varchar(512)    --comma-delimited field list
)
AS
insert into #tmp EXEC(@sql)
declare @msql varchar(3000)
set @msql = 'select * from #tmp order by ' + @sortClause
EXEC(@msql)
drop table #tmp
GO

Uyarı: Bunu test etmedim, ancak SQL Server 2005'te "çalışmalı" (sütunları önceden belirtmeden bir sonuç kümesinden geçici bir tablo oluşturacak.)


2

Bir noktada, bu tür bir bilgisayar korsanlığından kaçınmak için saklanan prosedürlerden uzaklaşıp sadece parametreleştirilmiş sorgular kullanmaya değmez mi?


1
Bazı durumlarda, belki de çivi üzerinde balyozlar olabilirler, ancak çoğu zaman doğrudan saklanan prosedürler üzerinde izinler ayarlamak (özellikle YÜRÜT) ve herhangi bir SQL sorgusunun doğrudan tablolara, hatta SELECT'lere karşı olmasına izin vermemek istiyoruz. Bilgisayar korsanlığını da pek sevmiyorum ama güvenlik benim yapmam gereken bir şey değil.
Sean Hanley

1
Bu yüzden bu kadar çok insan Nesne İlişkisel Haritalama'ya geçiyor. Sıralama için gereksiz gidiş-dönüşler, aynısı için devasa CASE blokları, gerçekten sadece birinin güncellenmesi gerektiğinde tonlarca sütuna yapılan anlamsız güncellemeler, vb. Hala kalan saklı yordamlar için kazanan tek argüman güvenliktir.
Pittsburgh DBA

ORM tam metin aramayı desteklemediği için bir ORM'den (EF) saklı yordama geçiyorum.
Ronnie Overby

@RonnieOverby Tam metin araması genellikle özel bir çözüm, örneğin Lucene ile daha iyi sunulur.
Hank Gay

@HankGay Varlık çerçevesinin Lucene'yi desteklemediğine dair garip bir his var.
Ronnie Overby

2

Katılıyorum, müşteri tarafını kullan. Ama duymak istediğiniz cevap bu değil gibi görünüyor.

Yani, olduğu gibi mükemmel. Neden onu değiştirmek isteyeceğinizi bilmiyorum, hatta "Daha iyi bir yol var mı?" Gerçekten, "Yol" olarak adlandırılmalı. Ayrıca, işe yarıyor ve projenin ihtiyaçlarını karşılayacak gibi görünüyor ve muhtemelen gelecek yıllar için yeterince genişletilebilir olacak. Veritabanlarınız vergilendirilmediğinden ve sıralama gerçekten çok kolay olduğundan, yıllarca bu şekilde kalmalıdır.

Ben terlemezdim.


Windows uygulamaları ile bu rotaya gittiğim için istemci tarafında bir sorunum yok. Peki ya web uygulamaları? Herhangi bir JavaScript çözümünü yeterince esnek bulmuyorum. Ve evet, söylediğim gibi çalışıyor, ama bu bir SQL kabusu. Elbette daha iyi yollar olup olmadığını bilmek isterim.
Sean Hanley

Daha yeni (2.0 ve üzeri) .NET kontrollerinde yerleşiktir. Veya kendinizinkini oluşturabilir ve bir veri görünümüne uygulayabilirsiniz. msdn.microsoft.com/en-us/library/hwf94875(VS.80).aspx
DS

2
Benim sorunum ölçeklenebilirlik ve performanstır. İstemci tarafında veya web sunucusu tarafında sıralama yapmak, her seferinde bir sayfada görüntüleyeceğiniz yalnızca 10 veya 15 yerine tüm verileri yüklemeyi gerektirir. Bu, uzun vadede son derece maliyetlidir, oysa veritabanı sıralamasında bu yoktur.
Sean Hanley

2

Sıralanmış sonuçları sayfaladığınızda, dinamik SQL iyi bir seçenektir. SQL enjeksiyonu konusunda paranoyak iseniz, sütun adı yerine sütun numaralarını kullanabilirsiniz. Azalan için negatif değerler kullanmadan önce bunu yaptım. Bunun gibi bir şey ...

declare @o int;
set @o = -1;

declare @sql nvarchar(2000);
set @sql = N'select * from table order by ' + 
    cast(abs(@o) as varchar) + case when @o < 0 then ' desc' else ' asc' end + ';'

exec sp_executesql @sql

O halde, sayının 1 ila # sütun arasında olduğundan emin olmanız yeterlidir. Hatta sütun numaralarının listesi için bu genişletmek ve benzeri bir işlev kullanarak ints bir tabloya o ayrıştırmak bu . O zaman cümleciklere göre siparişi oluşturursunuz ...

declare @cols varchar(100);
set @cols = '1 -2 3 6';

declare @order_by varchar(200)

select @order_by = isnull(@order_by + ', ', '') + 
        cast(abs(number) as varchar) + 
        case when number < 0 then ' desc' else '' end
from dbo.iter_intlist_to_tbl(@cols) order by listpos

print @order_by

Bir dezavantaj, istemci tarafındaki her sütunun sırasını hatırlamanız gerektiğidir. Özellikle tüm sütunları göstermediğinizde veya farklı bir sırayla görüntülediğinizde. İstemci sıralamak istediğinde, sütun adlarını sütun sırasına eşler ve ints listesini oluşturursunuz.


Dinamik raporlama sorguları oluşturmak için sp_executesql kullanıyoruz. Çok etkili. SQL, uygulamadan oluşturulamaz, ancak parametreler yalnızca gerektiği yere eklenir ve normal şekilde çalıştırılır.
Josh Smeaton

2

İstemci tarafında sıralamanın yapılmasına karşı bir argüman, büyük hacimli veriler ve sayfalandırmadır. Satır sayınız kolayca görüntüleyebileceğinizin ötesine geçtiğinde, genellikle SQL'de çalıştırmak isteyeceğiniz bir atlama / almanın parçası olarak sıralıyorsunuz.

Entity Framework için, metin aramanızı işlemek için bir saklı yordam kullanabilirsiniz. Aynı tür sorunuyla karşılaşırsanız, gördüğüm çözüm, arama için depolanmış bir işlem kullanmak ve maç için yalnızca bir kimlik anahtarı seti döndürmektir. Ardından, listedeki (içerir) kimlikleri kullanarak db'ye karşı yeniden sorgulayın (sıralama ile). EF, kimlik seti oldukça büyük olsa bile bunu oldukça iyi idare eder. Evet, bu iki gidiş-dönüş turdur, ancak sıralamanızı her zaman DB'de tutmanıza olanak tanır; bu, bazı durumlarda önemli olabilir ve saklı yordamda çok fazla mantık yazmanızı engeller.


1

SQL yerine sonuçları gösteren ızgaralar, raporlar vb. Üzerinde sıralama yapmaya ne dersiniz?

DÜZENLE:

Bu cevap daha önce reddedildiğinden beri bazı şeyleri açıklığa kavuşturmak için, biraz ayrıntıya gireceğim ...

İstemci tarafı ayırmayı bildiğinizi ancak bundan uzak durmak istediğinizi belirttiniz. Elbette bu senin çağrın.

Bununla birlikte, belirtmek istediğim şey, bunu istemci tarafında yaparak, verileri BİR KEZ çekebilir ve daha sonra onunla istediğiniz gibi çalışabilirsiniz - her seferinde sunucuya ileri geri birden çok yolculuk yapmak yerine sıralama değiştirilir.

SQL Server'ınız şu anda vergilendirilmiyor ve bu harika. Olmamalı. Ancak henüz aşırı yüklenmemiş olması, sonsuza kadar böyle kalacağı anlamına gelmez.

Web'de görüntülemek için daha yeni ASP.NET öğelerinden herhangi birini kullanıyorsanız, bu özelliklerin çoğu zaten pişirilmiştir.

Sıralamayı işlemek için her saklı yordama bu kadar çok kod eklemeye değer mi? Tekrar aramanız.

Nihayetinde onu desteklemekle sorumlu olacak kişi ben değilim. Ancak saklı yordamlar tarafından kullanılan çeşitli veri kümelerinde sütunlar eklendiğinde / kaldırıldığında neyin dahil edileceğini biraz düşünün (CASE ifadelerinde değişiklik yapılmasını gerektirir) veya aniden iki sütuna göre sıralamak yerine, kullanıcı üç sütuna ihtiyaç duyduğuna karar verir - şimdi bu yöntemi kullanan saklı yordamlarınızın her birini güncellemenizi gerektiriyor.

Benim için, çalışan bir istemci tarafı çözümü elde etmek ve bunu kullanıcıya dönük bir avuç veri ekranına uygulamak ve bununla bitmek buna değer. Yeni bir sütun eklenirse, zaten işlenmiştir. Kullanıcı birden çok sütuna göre sıralamak isterse, ikisine veya yirmi tanesine göre sıralayabilir.


Bu doğru yol olur, ancak "daha iyi bir yol" olarak görülmez
DS

Çünkü o zaman hala C # veya JavaScript'te kendi sıralamamı yazıyorum ve SQL'de çok daha kolay ve daha hızlı olması gerekiyor gibi görünüyor. İşte benim sorum. Bariz bir şeyi mi kaçırdım yoksa üzerinde çalıştığımız her lanet uygulamayı kendi özel sıralamanızı (C # veya JavaScript'te) yazmak zorunda mıyız?
Sean Hanley

3
Bekle, on binlerce satır içeren sonuç kümeleri ne olacak? Tüm bu verileri müşteriye iade edemezsiniz. Veritabanında sayfalama ve sıralama yapmanız gerekir.
Eric Z Beard

Yadyn, anlaşıldı. Ancak ızgaralarınız için genel bir sıralayıcıya sahip olduğunuzda, bunu tüm eşyalarınız için kullanırsınız.
Kevin Fairchild

Eric, Doğru ... Bu gibi durumlarda fazladan işleme ihtiyacınız var ve belki SQL içinde mantıklı olabilir. Doğru veya yanlış meselesi olmaktan uzaktır. Bazı durumlarda, istemcide SQL ve bazı durumlarda mantıklı olacaktır.
Kevin Fairchild

1

Üzgünüm partiye geç kaldım, ancak dinamik SQL'den gerçekten kaçınmak, ancak sunduğu esnekliği isteyenler için başka bir seçenek daha:

SQL'i anında dinamik olarak oluşturmak yerine, her olası varyasyon için benzersiz bir işlem oluşturmak için kod yazın. Ardından, arama seçeneklerine bakmak için koda bir yöntem yazabilir ve çağırmak için uygun proc'u seçmesini sağlayabilirsiniz.

Yalnızca birkaç varyasyonunuz varsa, işlemleri elle oluşturabilirsiniz. Ancak çok fazla varyasyonunuz varsa, hepsini korumak zorunda kalmak yerine, onları yeniden oluşturmak yerine proc jeneratörünüzü koruyabilirsiniz.

Ek bir avantaj olarak, bunu bu şekilde yaparak daha iyi performans için daha iyi SQL planları elde edeceksiniz.


-1

Bu çözüm yalnızca .NET'te çalışabilir, bilmiyorum.

Verileri ilk sıralama düzeni ile SQL sırasına göre C # 'a getiriyorum, bu verileri bir DataView'e koyuyorum, bir Session değişkeninde önbelleğe alıyorum ve bir sayfa oluşturmak için kullanıyorum.

Kullanıcı sıralamak (veya sayfayı veya filtrelemek) için bir sütun başlığına tıkladığında, veritabanına geri dönmem. Bunun yerine, önbelleğe alınmış DataView'a geri dönüyorum ve "Sort" özelliğini dinamik SQL'de yaptığım gibi dinamik olarak oluşturduğum bir ifadeye ayarlıyorum. ("RowFilter" özelliğini kullanarak filtrelemeyi aynı şekilde yapıyorum).

Bunu geldiğinde uygulamam, BugTracker.NET, bir demo çalışan hissetmek / görebilirsiniz http://ifdefined.com/btnet/bugs.aspx


TATLI! Bug tracker.NET harika!
digiguru

-7

Gerekmedikçe SQL Server sıralamasından kaçınmalısınız. Neden uygulama sunucusu veya istemci tarafında sıralama yapmıyorsunuz? Ayrıca .NET Generics olağanüstü sıralama yapar


6
Ölçeklenebilirlik nedeniyle. Birkaç bin sıra için sorun değil, ama on bin satır aşağı çekip bunu sıralamak istemiyorum. Yada daha fazla. Ayrıca, paging ne olacak? Genellikle sadece göstermem gereken şeyi çekmek isterim. 21-30 / 24056 satırlarının sıralanması yanlış olur.
Sean Hanley
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.