SQL संग्रहित प्रक्रियाओं के भीतर गतिशील छँटाई


126

यह एक ऐसा मुद्दा है जिसे मैंने अतीत में शोध करने में घंटों बिताए हैं। यह मुझे ऐसा लगता है जो आधुनिक आरडीबीएमएस समाधानों द्वारा संबोधित किया जाना चाहिए था, लेकिन अभी तक मुझे ऐसा कुछ भी नहीं मिला है जो वास्तव में मुझे किसी भी वेब या विंडोज एप्लिकेशन में डेटाबेस बैक-एंड के साथ एक अविश्वसनीय रूप से सामान्य आवश्यकता के रूप में संबोधित करता हो।

मैं डायनेमिक सॉर्टिंग की बात करता हूं। मेरी काल्पनिक दुनिया में, यह कुछ के समान सरल होना चाहिए:

ORDER BY @sortCol1, @sortCol2

यह नौसिखिया उदाहरण है जो पूरे इंटरनेट पर मंचों पर नौसिखिया एसक्यूएल और संग्रहित प्रक्रिया डेवलपर्स द्वारा दिया गया है । "यह क्यों संभव नहीं है?" वे पूछते हैं। वास्तव में, कोई व्यक्ति अंततः उन्हें संग्रहीत प्रक्रियाओं की संकलित प्रकृति, सामान्य रूप से निष्पादन योजनाओं और सभी अन्य प्रकार के अन्य कारणों के बारे में व्याख्यान देने के लिए आता है, जो एक पैरामीटर को सीधे एक ORDER BYखंड में रखना संभव नहीं है ।


मुझे पता है कि आप में से कुछ पहले से ही क्या सोच रहे हैं: "ग्राहक को छंटाई करने दें, फिर।" स्वाभाविक रूप से, यह आपके डेटाबेस से काम को बंद कर देता है। हालांकि हमारे मामले में, हमारे डेटाबेस सर्वर भी 99% समय के पसीने को नहीं तोड़ रहे हैं और वे अभी भी मल्टी-कोर नहीं हैं या सिस्टम आर्किटेक्चर में हर 6 महीने में होने वाले अन्य असंख्य सुधारों में से एक हैं। अकेले इस कारण से, हमारे डेटाबेस को छांटने में समस्या नहीं होगी। इसके अतिरिक्त, डेटाबेस बहुत हैंछँटाई में अच्छा। वे इसके लिए अनुकूलित हैं और इसे सही करने के लिए वर्षों से हैं, इसे करने के लिए भाषा अविश्वसनीय रूप से लचीली, सहज और सरल है और सभी किसी भी शुरुआती SQL लेखक को पता है कि यह कैसे करना है और इससे भी अधिक महत्वपूर्ण बात यह है कि वे इसे संपादित करना जानते हैं, परिवर्तन करें, रखरखाव करें, आदि। जब आपके डेटाबेस पर कर लगने से दूर हैं और आप बस (और छोटा!) विकास समय चाहते हैं तो यह एक स्पष्ट विकल्प लगता है।

फिर वेब मुद्दा है। मैंने जावास्क्रिप्ट के साथ चारों ओर खेला है जो HTML तालिकाओं के क्लाइंट-साइड सॉर्टिंग करेगा, लेकिन वे अनिवार्य रूप से मेरी आवश्यकताओं के लिए पर्याप्त रूप से लचीले नहीं हैं और फिर से, चूंकि मेरे डेटाबेस पर अत्यधिक कर नहीं हैं और वास्तव में वास्तव में आसानी से छँटाई कर सकते हैं, मैं एक मुश्किल समय को फिर से लिखने या रोल-माय-खुद के जावास्क्रिप्ट सॉर्टर में लगने वाले समय को उचित ठहराना होगा। वही आम तौर पर सर्वर-साइड सॉर्टिंग के लिए जाता है, हालांकि यह पहले से ही जावास्क्रिप्ट पर बहुत पसंद किया जाता है। मैं ऐसा नहीं हूं जो विशेष रूप से डेटासेट के ओवरहेड को पसंद करता हूं, इसलिए मुझे मुकदमा करो।

लेकिन यह इस बिंदु को वापस लाता है कि यह संभव नहीं है - या बल्कि, आसानी से नहीं। मैंने पूर्व प्रणालियों के साथ किया है, गतिशील छँटाई करने का एक अविश्वसनीय रूप से हैक तरीका। यह सुंदर नहीं था, न ही सहज, सरल, या लचीला और एक शुरुआती SQL लेखक सेकंड के भीतर खो जाएगा। पहले से ही यह इतना "समाधान" नहीं बल्कि एक "जटिलता" है।


निम्नलिखित उदाहरण किसी भी प्रकार की सर्वोत्तम प्रथाओं या अच्छी कोडिंग शैली या किसी भी चीज़ को उजागर करने के लिए नहीं हैं, और न ही वे टी-एसक्यूएल प्रोग्रामर के रूप में मेरी क्षमताओं का संकेत हैं। वे वही हैं जो मैं कर रहा हूं और मैं पूरी तरह से मानता हूं कि वे भ्रामक, खराब रूप और सिर्फ सादे हैक हैं।

हम एक पूर्णांक मान को एक संग्रहीत प्रक्रिया के पैरामीटर के रूप में पास करते हैं (चलो पैरामीटर को केवल "सॉर्ट" कहते हैं) और उसी से हम अन्य चर का एक गुच्छा निर्धारित करते हैं। उदाहरण के लिए ... मान लें कि क्रमांक 1 है (या डिफ़ॉल्ट):

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

आप पहले से ही देख सकते हैं कि अगर मैंने अन्य कॉलमों को परिभाषित करने के लिए और अधिक @colX चर घोषित किए तो मैं वास्तव में "सॉर्ट" के मूल्य के आधार पर सॉर्ट करने के लिए कॉलम के साथ रचनात्मक हो सकता था ... इसका उपयोग करने के लिए, यह आमतौर पर निम्नलिखित की तरह लग रहा है अविश्वसनीय रूप से गड़बड़ क्लॉज:

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

जाहिर है यह बहुत ही नीचे का उदाहरण है। असली सामान, चूँकि हमारे पास आमतौर पर छाँटने के लिए चार या पाँच स्तंभ होते हैं, प्रत्येक संभव माध्यमिक या यहाँ तक कि इसके अलावा क्रमबद्ध करने के लिए एक तीसरा स्तंभ होता है (उदाहरण के लिए अवरोह के बाद फिर आरोही नाम से दूसरा क्रमबद्ध) और प्रत्येक सहायक द्वि-। दिशात्मक छंटाई जो प्रभावी रूप से मामलों की संख्या को दोगुना करती है। हाँ ... यह बहुत जल्दी बालों वाली हो जाती है।

विचार यह है कि कोई व्यक्ति "आसानी से" सॉर्ट मामलों को बदल सकता है जैसे कि वाहन चालक को स्टोरेजटाइम से पहले सॉर्ट किया जाता है ... लेकिन छद्म-लचीलेपन, कम से कम इस सरल उदाहरण में, वास्तव में समाप्त होता है। अनिवार्य रूप से, प्रत्येक मामला जो एक परीक्षण में विफल रहता है (क्योंकि हमारी सॉर्ट विधि इस बार उस पर लागू नहीं होती है) एक पूर्ण मान प्रदान करता है। और इस प्रकार आप एक क्लॉज के साथ समाप्त होते हैं जो निम्नलिखित की तरह कार्य करता है:

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

तुम्हें नया तरीका मिल गया है। यह काम करता है क्योंकि SQL सर्वर प्रभावी रूप से खंडों द्वारा शून्य मानों की उपेक्षा करता है। यह बनाए रखने के लिए अविश्वसनीय रूप से कठिन है, क्योंकि SQL के किसी भी बुनियादी काम के ज्ञान के साथ कोई भी शायद देख सकता है। अगर मैंने आप में से किसी को खो दिया है, तो बुरा मत मानिए। हमें इसे काम करने में लंबा समय लगा और हम अभी भी इसे संपादित करने या इसके जैसे नए बनाने की कोशिश में भ्रमित हैं। शुक्र है कि इसे अक्सर बदलने की आवश्यकता नहीं है, अन्यथा यह जल्दी से "मुसीबत के लायक नहीं" बन जाएगा।

अभी तक यह किया था काम।


मेरा सवाल तब है: क्या कोई बेहतर तरीका है?

मैं संग्रहीत प्रक्रिया वाले लोगों के अलावा अन्य समाधानों के साथ ठीक हूं, क्योंकि मुझे एहसास है कि यह सिर्फ जाने का तरीका नहीं हो सकता है। अधिमानतः, मैं यह जानना चाहूंगा कि क्या कोई इसे संग्रहीत प्रक्रिया के भीतर बेहतर कर सकता है, लेकिन यदि नहीं, तो आप कैसे सभी को ASP.NET के साथ उपयोगकर्ता को डेटा की डायनेमिक रूप से सॉर्ट टेबल (द्वि-प्रत्यक्ष, बहुत) की सुविधा देते हैं?

और इतने लंबे प्रश्न को पढ़ने (या कम से कम स्किमिंग) के लिए धन्यवाद!

पुनश्च: मुझे खुशी है कि मैंने एक संग्रहीत प्रक्रिया का अपना उदाहरण नहीं दिखाया जो डायनेमिक सॉर्टिंग, डायनेमिक फ़िल्टरिंग / कॉलम की खोज-खोज का समर्थन करता है, ROWNUMBER () के माध्यम से पृष्ठांकन, और प्रयास करें ... त्रुटियों पर लेन-देन रोलबैकिंग के साथ पकड़ ... "behemoth- आकार" भी उन्हें वर्णन करने के लिए शुरू नहीं करता है।


अपडेट करें:

  • मैं डायनेमिक SQL से बचना चाहूंगा । एक स्ट्रिंग को एक साथ पार्स करना और उस पर एक EXEC चलाना पहली जगह में एक संग्रहीत प्रक्रिया होने के उद्देश्य को बहुत कुछ हरा देता है। कभी-कभी मुझे आश्चर्य होता है कि अगर ऐसा काम करने का विवेक इसके लायक नहीं होगा, तो कम से कम इन विशेष गतिशील छंटाई के मामलों में। फिर भी, मैं हमेशा गंदे महसूस करता हूं जब भी मैं इस तरह से गतिशील SQL स्ट्रिंग्स करता हूं - जैसे मैं अभी भी क्लासिक एएसपी दुनिया में रह रहा हूं।
  • सुरक्षा के लिए पहली जगह में संग्रहीत प्रक्रियाओं के बहुत सारे कारण हम चाहते हैं । मुझे सुरक्षा चिंताओं पर कॉल करने के लिए नहीं मिलता है, केवल समाधान सुझाते हैं। SQL सर्वर 2005 के साथ हम अलग-अलग संग्रहीत प्रक्रियाओं पर स्कीमा स्तर पर अनुमतियाँ सेट कर सकते हैं (यदि आवश्यकता हो तो प्रति-उपयोगकर्ता के आधार पर) और फिर सीधे तालिकाओं के विरुद्ध किसी भी प्रश्न को अस्वीकार कर सकते हैं। इस दृष्टिकोण के पेशेवरों और विपक्षों की आलोचना शायद एक और सवाल के लिए है, लेकिन फिर से यह मेरा निर्णय नहीं है। मैं सिर्फ लीड कोड बंदर हूं। :)

देखें stackoverflow.com/questions/3659981/... द्वारा एसक्यूएल सर्वर गतिशील आदेश मिश्रित डेटाटाइप्स साथ - बहुत
LCJ

डायनेमिक SQL FAR का सबसे बेहतर तरीका है ... IF [और यह एक बड़ा IF] है। आपका डेटा एक्सेस लेयर सख्त है और आपका डायनेमिक SQL एक सिस्टम द्वारा जनरेट किया जाता है, जो RDBMS नियमों के साथ सही रूप में व्यक्त कठोर प्रोग्राम के साथ प्रोग्राम किया गया है। एक अल्गोरिदमिक रूप से इंजीनियर डेटाबेस आर्किटेक्चर सुंदरता की एक चीज है ...
hajikelist

जवाबों:


97

हाँ, यह एक दर्द है, और जिस तरह से आप इसे कर रहे हैं वह मेरे जैसा दिखता है:

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

यह, मेरे लिए, कोड से गतिशील एसक्यूएल के निर्माण की तुलना में अभी भी बहुत बेहतर है, जो डीबीए के लिए एक स्केलेबिलिटी और रखरखाव दुःस्वप्न में बदल जाता है।

मैं कोड से क्या करता हूं, पेजिंग को रिफलेक्टर करता हूं और छंटाई करता हूं, इसलिए कम से कम मेरे पास बहुत अधिक पुनरावृत्ति नहीं है, जिसके लिए @SortExprऔर मान को पॉप्युलेट करने के लिए @SortDir

जहाँ तक एसक्यूएल का सवाल है, डिज़ाइन और फॉर्मेट को अलग-अलग संग्रहीत प्रक्रियाओं के बीच रखें, इसलिए जब आप बदलाव करने जाएं तो कम से कम साफ-सुथरा और पहचानने योग्य हो।


1
बिल्कुल सही। मेरा लक्ष्य एक बड़े 5000 varchar string पर EXEC कमांड करने से बचना था। सब कुछ हम संग्रहीत प्रक्रियाओं के माध्यम से किया जाना चाहिए यदि केवल अतिरिक्त सुरक्षा के लिए है क्योंकि हम स्कीमा स्तर पर उन पर अनुमति दे सकते हैं। स्केलेबिलिटी और प्रदर्शन लाभ हमारे मामले में सिर्फ एक प्लस हैं।
सीन हैली

1
{सुरक्षा, मापनीयता, प्रदर्शन} के लिए रख-रखाव जोड़ें। एक बार जब आपके पास आपके DB के खिलाफ चल रहे गतिशील SQL के साथ 3 या 4 ऐप होते हैं, तो आप खराब हो जाते हैं, आप कुछ भी नहीं बदल सकते हैं, खासकर जब ऐप्स की उम्र और डेवलपर्स आगे बढ़ते हैं। Exec और डायनेमिक sql बुराई है।
एरिक जेड बियर्ड

यह सिर्फ यह है --- हम पहले से ही करते हैं, इससे पहले कि मैं यहाँ पहुँच गया, अभी भी चल रहे सभी के लिए एएसपी वेब ऐप और कई, कई एक्सेस वीबी ऐप अभी भी घूम रहे हैं। मुझे चिकोटी काटने और किसी भी समय रखरखाव करने के लिए किसी भी समय भड़काने वाली गलतियों को ठीक करने का आग्रह करना पड़ता है।
सीन हैली

1
यह वही है जो मैं भी करता हूं, सिवाय इसके कि मैं दिशा को SortExpr में शामिल करता हूं: ORDER BY CASE WHEN sort = 'FirstName' THEN FirstName END ASC, CASE WHEN sort = '-FirstName THEN FirstName END DESC
माइकल ब्रे

यह समान रूप से डीबीए और सॉफ्टवेयर इंजीनियरों के लिए बुरा सपना है। इसलिए डायनामिक लेकिन सख्त सिस्टम में सक्षम होने के बजाय आपकी सूचना स्कीमा के आधार पर अभिव्यंजक एसक्यूएल स्टेटमेंट उत्पन्न करते हैं जो आपके पास हार्डकोड किए गए ग्लिबिश की यह घृणित चमक है। यह सबसे अच्छा है पर गरीब प्रोग्रामिंग है।
हजिकेलिस्ट

23

यह दृष्टिकोण क्रमबद्ध कॉलमों को क्रम से दो बार डुप्लिकेट होने से बचाता है, और थोड़ा अधिक पढ़ने योग्य IMO है:

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

यह एक अच्छा जवाब की तरह लग रहा था, लेकिन जब काम करने योग्य कॉलम में अलग-अलग
डेटाैटिप्स होते हैं

6

डायनेमिक SQL अभी भी एक विकल्प है। आपको बस यह तय करना है कि आपके पास वर्तमान में जो विकल्प है, उससे अधिक विकल्प क्या है।

यहाँ एक लेख है जो दिखाता है कि: http://www.4guysfromrolla.com/webtech/010704-1.shtml


6

मेरे अनुप्रयोग यह बहुत करते हैं, लेकिन वे सभी गतिशील रूप से SQL का निर्माण कर रहे हैं। हालांकि, जब मैं संग्रहीत प्रक्रियाओं से निपटता हूं तो मैं ऐसा करता हूं:

  1. संग्रहीत कार्यविधि को एक फ़ंक्शन बनाएं जो आपके मूल्यों की तालिका लौटाता है - कोई प्रकार नहीं।
  2. फिर अपने एप्लिकेशन कोड में ऐसा करें select * from dbo.fn_myData() where ... order by ...ताकि आप गतिशील रूप से वहां के क्रम को निर्दिष्ट कर सकें।

फिर कम से कम डायनामिक हिस्सा आपके एप्लिकेशन में है, लेकिन डेटाबेस अभी भी भारी उठाने का काम कर रहा है।


1
यह शायद सबसे अच्छा समझौता है जो मैंने अभी तक गतिशील एसक्यूएल और संग्रहीत प्रक्रियाओं का एक साथ उपयोग करने के बीच देखा है। मुझें यह पसंद है। मैं एक समान दृष्टिकोण के साथ कभी-कभी प्रयोग कर सकता हूं, लेकिन हमारे मौजूदा चालू परियोजनाओं में से किसी में भी ऐसा परिवर्तन निषेधात्मक होगा।
शॉन हैनले

1
आप सारणीबद्ध फ़ंक्शन रिटर्निंग डेटा के बजाय स्थानीय टेबल चर का उपयोग करके समान प्राप्त कर सकते हैं। मैं स्थानीय तालिकाओं को कार्यों से अधिक लचीला पाता हूं, क्योंकि आप कुछ डिबग जानकारी का उत्पादन कर सकते हैं।
संजय ज़ल्के

5

एक संग्रहीत कार्यविधि तकनीक (हैक?) मैंने कुछ कामों के लिए गतिशील एसक्यूएल से बचने के लिए उपयोग किया है एक अद्वितीय सॉर्ट कॉलम है। अर्थात,

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

यह प्रस्तुत करने में आसान है - आप अपने mySort कॉलम में फ़ील्ड सम्‍मिलित कर सकते हैं, गणित या दिनांक कार्यों के साथ आदेश को उलट सकते हैं, आदि।

अधिमानतः, हालांकि, मैं अपने asp.net ग्रिडव्यू या अन्य ऑब्जेक्ट का उपयोग बिल्ड-इन सॉर्टिंग के लिए करता हूं, जो कि मेरे लिए सॉर्ट करने के लिए डेटा फ़्रेक Sql-Server को पुनः प्राप्त करता है। या यहां तक ​​कि अगर यह अंतर्निहित नहीं है - जैसे, asp.net में डेटाटैबल्स, आदि।


4

वहाँ कुछ अलग अलग तरीकों से आप इसे हैक कर सकते हैं।

आवश्यक शर्तें:

  1. सपा में केवल एक का चयन करें
  2. किसी भी छँटाई को छोड़ दें (या एक डिफ़ॉल्ट है)

फिर एक अस्थायी तालिका में डालें:

create table #temp ( your columns )

insert #temp
exec foobar

select * from #temp order by whatever

विधि # 2: एक लिंक किए गए सर्वर को स्वयं पर सेट करें, फिर ओपनक्वेरी का उपयोग करके इस से चुनें: http://www.sommarskog.se/share_data.html#OPENQUERY


4

एक तीसरा विकल्प हो सकता है, क्योंकि आपके सर्वर में बहुत सारे चक्र हैं - एक अस्थायी तालिका के माध्यम से छँटाई करने के लिए एक सहायक प्रक्रिया का उपयोग करें। कुछ इस तरह

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

कैविएट: मैंने इसका परीक्षण नहीं किया है, लेकिन यह SQL सर्वर 2005 में "काम" करना चाहिए (जो पहले से कॉलम निर्दिष्ट किए बिना एक परिणाम सेट से एक अस्थायी तालिका बनाएगा।)


2

कुछ बिंदु पर, यह संग्रहीत प्रक्रियाओं से दूर जाने के लिए इसके लायक नहीं बन जाता है और सिर्फ इस तरह की हैकरी से बचने के लिए पैरामीटर किए गए प्रश्नों का उपयोग करता है?


1
कुछ मामलों में हो सकता है कि वे एक कील पर स्लेजहैमर हों, लेकिन अक्सर हम अनुमतियों (विशेष रूप से जांच) को सीधे संग्रहीत प्रक्रियाओं पर सेट करना चाहते हैं और किसी भी एसक्यूएल प्रश्नों को सीधे तालिकाओं के खिलाफ अस्वीकार कर देते हैं, यहां तक ​​कि चयन भी। मुझे हैकरी बहुत पसंद नहीं है, लेकिन सुरक्षा बनाने के लिए मेरी कॉल नहीं है।
सीन हनले

1
यही कारण है कि इतने सारे लोग ऑब्जेक्ट रिलेशनल मैपिंग के लिए आगे बढ़ रहे हैं। छंटाई के लिए अनावश्यक दौर यात्राएं, उसी के लिए विशाल CASE ब्लॉक, जब वे वास्तव में केवल एक अद्यतन किए जाने की आवश्यकता होती है, आदि स्तंभों के टन करने के लिए संवेदनाहीन अपडेट, संग्रहीत प्रक्रियाओं के लिए एक जीतने वाला तर्क जो अभी भी सुरक्षा है।
पिट्सबर्ग डीबीए

मैं ORM (EF) से एक संग्रहित प्रक्रिया में जा रहा हूं क्योंकि ORM पूर्ण पाठ खोज का समर्थन नहीं करता है।
रॉनी ओवरबी

@ रोनीओवेर्बी पूर्ण-पाठ खोज अक्सर एक समर्पित समाधान, जैसे, ल्यूसिन द्वारा बेहतर ढंग से परोसी जाती है।
हांक गे

@ हंकाई मुझे अजीब लग रहा है कि इकाई ढांचा भी ल्यूसीन का समर्थन नहीं करता है।
रॉनी ओवरबी

2

मैं सहमत हूं, ग्राहक पक्ष का उपयोग करें। लेकिन ऐसा प्रतीत होता है कि वह उत्तर नहीं है जिसे आप सुनना चाहते हैं।

तो, यह सही तरीका है। मुझे नहीं पता कि आप इसे क्यों बदलना चाहते हैं, या यहां तक ​​कि पूछें "क्या कोई बेहतर तरीका है।" वास्तव में, इसे "द वे" कहा जाना चाहिए। इसके अलावा, यह काम करने के लिए लगता है और परियोजना की आवश्यकताओं के अनुरूप है और शायद आने वाले वर्षों के लिए पर्याप्त रूप से विस्तारित होगा। चूंकि आपके डेटाबेस पर कर नहीं लगाया गया है और छंटनी वास्तव में आसान है इसलिए इसे आने वाले वर्षों तक इसी तरह रहना चाहिए।

मैं इसे पसीना नहीं होगा।


मुझे क्लाइंट-साइड से कोई समस्या नहीं है, क्योंकि मैं विंडोज ऐप के साथ उस रूट पर जाता हूं। लेकिन वेब ऐप्स का क्या? मैं वास्तव में पर्याप्त लचीला किसी भी जावास्क्रिप्ट समाधान नहीं मिल रहा है। और हाँ, यह काम करता है जैसा कि मैंने कहा कि हमारे पास यह है, लेकिन यह एसक्यूएल का एक बुरा सपना है। निश्चित रूप से मैं यह जानना चाहूंगा कि क्या बेहतर तरीके हैं।
सीन हनले

यह नए (2.0 और ऊपर) .NET कंट्रोल में बनाया गया है। या आप अपना खुद का बना सकते हैं और इसे डेटाव्यू पर लागू कर सकते हैं। msdn.microsoft.com/en-us/library/hwf94875(VS.80).aspx
DS

2
मेरी समस्या तब स्केलेबिलिटी और प्रदर्शन में से एक है। क्लाइंट-साइड या वेब-सर्वर-साइड सॉर्टिंग को केवल 10 या 15 के बजाय सभी डेटा लोड करने की आवश्यकता होती है जो आप एक समय में एक पृष्ठ पर प्रदर्शित करने जा रहे हैं। यह बहुत महंगा है, लंबे समय में, जबकि डेटाबेस छँटाई में ऐसा नहीं है।
सीन हैनली

2

जब आप हल किए गए परिणामों को पृष्ठांकित कर रहे हैं, तो गतिशील SQL एक अच्छा विकल्प है। यदि आप SQL इंजेक्शन के बारे में पागल हैं, तो आप कॉलम नाम के बजाय कॉलम नंबर का उपयोग कर सकते हैं। उतरने के लिए नकारात्मक मूल्यों का उपयोग करने से पहले मैंने ऐसा किया है। कुछ इस तरह...

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

फिर आपको केवल यह सुनिश्चित करने की आवश्यकता है कि संख्या कॉलम के # 1 के अंदर है। आप इसे स्तंभ संख्याओं की सूची में भी विस्तारित कर सकते हैं और पार्स कर सकते हैं कि इस तरह के एक फ़ंक्शन का उपयोग करके तालिका की एक तालिका में । तब आप इस तरह से क्लॉज करके ऑर्डर का निर्माण करेंगे ...

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

एक दोष यह है कि आपको ग्राहक के प्रत्येक कॉलम के क्रम को याद रखना होगा। विशेष रूप से, जब आप सभी कॉलम प्रदर्शित नहीं करते हैं या आप उन्हें एक अलग क्रम में प्रदर्शित करते हैं। जब क्लाइंट सॉर्ट करना चाहता है, तो आप कॉलम नामों को कॉलम ऑर्डर पर मैप करते हैं और इन्ट्स की सूची जेनरेट करते हैं।


हम गतिशील रिपोर्टिंग प्रश्नों के निर्माण के लिए sp_executesql का उपयोग करते हैं। बहुत ही प्रभावी। SQL अनुप्रयोग से नहीं बनाया जा सकता है, लेकिन मापदंडों को केवल जहां आवश्यक हो डाला जाता है और सामान्य रूप से निष्पादित किया जाता है।
जोश स्मेटन

2

क्लाइंट पक्ष पर सॉर्टिंग करने के विरुद्ध एक तर्क बड़ी मात्रा में डेटा और पृष्ठांकन है। एक बार जब आपकी पंक्ति गणना से आगे निकल जाती है तो आप आसानी से प्रदर्शित कर सकते हैं कि आप अक्सर स्किप / टेक के हिस्से के रूप में छँटाई कर रहे हैं, जिसे आप शायद SQL में चलाना चाहते हैं।

एंटिटी फ्रेमवर्क के लिए, आप अपनी पाठ खोज को संभालने के लिए संग्रहीत कार्यविधि का उपयोग कर सकते हैं। यदि आप एक ही प्रकार की समस्या का सामना करते हैं, तो जो समाधान मैंने देखा है, वह खोज के लिए संग्रहीत खरीद का उपयोग करना है, मैच के लिए केवल एक आईडी कुंजी सेट लौटाता है। अगला, एक सूची (शामिल) में आईडी का उपयोग करके db के खिलाफ फिर से क्वेरी (सॉर्ट के साथ)। आईडी सेट बहुत बड़ा होने पर भी ईएफ इसे बहुत अच्छी तरह से संभालता है। हां, यह दो दौर की यात्राएं हैं, लेकिन यह आपको डीबी में हमेशा अपनी छंटाई रखने की अनुमति देता है, जो कुछ स्थितियों में महत्वपूर्ण हो सकता है, और आपको संग्रहीत प्रक्रिया में तर्क का एक बोझ लिखने से रोकता है।


1

एसक्यूएल के बजाय परिणाम - ग्रिड, रिपोर्ट आदि प्रदर्शित करने वाले सामान पर छंटनी के बारे में कैसे?

संपादित करें:

चीजों को स्पष्ट करने के लिए क्योंकि यह उत्तर पहले से नीचे दिया गया था, मैं थोड़ा विस्तार करूँगा ...

आपने कहा कि आप क्लाइंट-साइड सॉर्टिंग के बारे में जानते हैं, लेकिन इसे स्पष्ट करना चाहते हैं। वह आपकी कॉल है।

हालांकि, मैं यह बताना चाहता हूं कि क्लाइंट-साइड पर ऐसा करने से, आप ONCE डेटा को खींच सकते हैं और फिर इसके साथ काम कर सकते हैं - हालांकि, हर बार सर्वर के आगे और पीछे कई ट्रिप करना। तरह बदल जाता है।

आपके SQL सर्वर पर अभी कर नहीं लग रहा है और यह बहुत बढ़िया है। यह नहीं होना चाहिए। लेकिन सिर्फ इसलिए कि यह अतिभारित नहीं है, इसका मतलब यह नहीं है कि यह हमेशा की तरह रहेगा।

यदि आप वेब पर प्रदर्शित होने के लिए किसी भी नए ASP.NET सामान का उपयोग कर रहे हैं, तो बहुत सारा सामान पहले से ही सही है।

क्या यह प्रत्येक संग्रहित प्रक्रिया में इतना कोड जोड़ने के लायक है कि केवल छँटाई को संभालना है? फिर से, आपका फोन।

मैं वह नहीं हूं जो अंततः इसका समर्थन करने का प्रभारी होगा। लेकिन कुछ को यह बताएं कि कॉलम में जोड़े गए / हटाए गए विभिन्न डेटासेट्स के भीतर क्या शामिल होगा, जो संग्रहीत प्रक्रियाओं द्वारा उपयोग किए जाते हैं (CASE स्टेटमेंट में संशोधन की आवश्यकता होती है) या जब अचानक दो कॉलमों को छांटने के बजाय, उपयोगकर्ता निर्णय लेता है कि उन्हें तीन की आवश्यकता है - अब आपको इस पद्धति का उपयोग करने वाली अपनी संग्रहीत सभी प्रक्रियाओं को अपडेट करने की आवश्यकता है।

मेरे लिए, यह काम करने वाले क्लाइंट-साइड समाधान प्राप्त करने और डेटा के उपयोगकर्ता-सामना करने वाले डिस्प्ले के मुट्ठी भर में लागू करने के लिए इसके लायक है और इसके साथ किया जाना चाहिए। यदि कोई नया स्तंभ जोड़ा गया है, तो यह पहले से ही संभाला हुआ है। यदि उपयोगकर्ता कई कॉलमों को क्रमबद्ध करना चाहता है, तो वे उनमें से दो या बीस प्रकारों को क्रमबद्ध कर सकते हैं।


यह सही तरीका होगा, लेकिन "बेहतर तरीका" नहीं माना जाता है
डीएस

क्योंकि तब मैं अभी भी C # या जावास्क्रिप्ट में अपनी खुद की छँटाई लिख रहा हूँ और ऐसा लगता है कि यह SQL में इतना आसान और तेज होना चाहिए। इस प्रकार मेरा प्रश्न। क्या मुझे कुछ स्पष्ट याद आ रहा था या क्या हम अपने स्वयं के कस्टम सॉर्टिंग (सी # या जावास्क्रिप्ट में) लिख रहे हैं, जिस पर हम काम करते हैं?
शॉन हैनले

3
रुको, परिणाम के बारे में हजारों पंक्तियों के दसियों के साथ क्या सेट करता है? आप ग्राहक को वह सारा डेटा नहीं लौटा सकते। आपको डेटाबेस पर पेजिंग और सॉर्टिंग करनी है।
एरिक जेड

यद्दीन, समझ गया। लेकिन एक बार जब आपके पास ग्रिड के लिए एक सामान्य सॉर्टर होता है, तो आप बस अपने सभी सामानों के लिए इसका उपयोग करते हैं।
केविन फेयरचाइल्ड

एरिक, सच ... इस तरह के मामलों में, आपको अतिरिक्त हैंडलिंग की आवश्यकता होती है और शायद यह SQL के भीतर समझ में आता है। यह एक सही बनाम गलत मुद्दे से दूर है। कुछ मामलों में, यह ग्राहक के लिए SQL और कुछ मामलों के लिए समझ में आएगा।
केविन फेयरचाइल्ड

1

क्षमा करें, मुझे पार्टी में देर हो गई है, लेकिन यहां उन लोगों के लिए एक और विकल्प है जो वास्तव में गतिशील एसक्यूएल से बचना चाहते हैं, लेकिन यह लचीलापन प्रदान करता है:

फ्लाई पर एसक्यूएल को गतिशील रूप से उत्पन्न करने के बजाय, प्रत्येक संभावित भिन्नता के लिए एक अद्वितीय खरीद उत्पन्न करने के लिए कोड लिखें। तब आप खोज विकल्पों को देखने के लिए कोड में एक विधि लिख सकते हैं और इसे कॉल करने के लिए उपयुक्त खरीद का चयन कर सकते हैं।

यदि आपके पास केवल कुछ भिन्नताएं हैं तो आप केवल हाथों से प्रॉक्सेस बना सकते हैं। लेकिन अगर आपके पास बहुत अधिक विविधताएं हैं, तो उन सभी को बनाए रखने के बजाय, आप अपने खरीद जनरेटर को बनाए रखने के बजाय इसे फिर से बनाएंगे।

अतिरिक्त लाभ के रूप में, आपको बेहतर प्रदर्शन के लिए बेहतर एसक्यूएल योजनाएं मिलेंगी।


-1

यह समाधान केवल .NET में काम कर सकता है, मुझे नहीं पता।

मैं डेटा को C # में प्रारंभिक क्रम से क्लॉज द्वारा SQL क्रम में लाता हूं, उस डेटा को DataView में रखता हूं, इसे एक सेशन चर में कैश करता हूं, और पेज बनाने के लिए इसका उपयोग करता हूं।

जब उपयोगकर्ता कॉलम (या पृष्ठ, या फ़िल्टर) पर जाने वाले कॉलम पर क्लिक करता है, तो मैं डेटाबेस में वापस नहीं जाता। इसके बजाय, मैं अपने कैश्ड DataView पर वापस जाता हूं और अपनी "सॉर्ट" संपत्ति को एक अभिव्यक्ति पर सेट करता हूं जिसे मैं गतिशील रूप से बनाता हूं, जैसे मैं SQL को गतिशील करूंगा। (मैं "रोफिल्टर" संपत्ति का उपयोग करके उसी तरह से फ़िल्टरिंग करता हूं)।

आप http://ifdefined.com/btnet/bugs.aspx पर मेरे ऐप, BugTracker.NET के डेमो में इसे देख / महसूस कर सकते हैं


मिठाई! बग tracker.NET चट्टानों!
डिजीगुरू

-7

यदि आवश्यक हो, तो आपको SQL सर्वर सॉर्टिंग से बचना चाहिए। ऐप सर्वर या क्लाइंट की तरफ क्यों नहीं छांटा जाता? इसके अलावा .NET जेनरिक असाधारण सॉर्टिन करता है


6
स्केलेबिलिटी की वजह से। यह कुछ हज़ार पंक्तियों के लिए ठीक है, लेकिन मैं दस हज़ार को नीचे नहीं खींचना चाहता और इसे छाँटना चाहता हूँ। या ज्यादा। इसके अलावा, पेजिंग के बारे में क्या? मैं अक्सर केवल वही प्रदर्शित करना चाहता हूं जिसे मुझे प्रदर्शित करने की आवश्यकता है। तथ्य गलत होने के बाद २४०५६ की धारा १ ९९ २ को छाँटना गलत होगा।
सीन हैनले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.