6

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

यह मेरा प्रकार है:

CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
    [VwdCode] [varchar](50) NOT NULL 
) 

और इस एसक्यूएल में से एक है जहां इसका इस्तेमाल होता है: के रूप में आप मैं ROW_NUMBER उपयोग कर रहा हूँ तरह-स्तंभ प्राप्त करने के लिए देख सकते हैं

/// <summary> 
///  Inserts all new WatchListCodes for a given watchlist 
/// </summary> 
public const string InsertWatchListCodes = @" 
INSERT INTO [dbo].[WatchListCodes] 
    ([WatchListID] 
    ,[VwdCode] 
    ,[Sort]) 
SELECT @WatchListID, VwdCode, ROW_NUMBER()OVER(ORDER BY (SELECT 1)) 
FROM @VwdCodeList;"; 

मूल्य।

क्या मुझे तालिका-प्रकार में एक प्रकार-कॉलम जोड़ने की आवश्यकता है या क्या यह गारंटीकृत है (दस्तावेज) कि यह वही रहता है? ऐसा लगता है कि काम करता है। एक IEnumerable<string> के लिए

SqlParameter vwdCodeListParameter = insertWatchListCodeCommand.Parameters.Add("@VwdCodeList", SqlDbType.Structured); 
vwdCodeListParameter.TypeName = "[dbo].[VwdCodeList]"; 
vwdCodeListParameter.Value = WatchListSql.GetVwdCodeRecords(newVwdCodes, true); 
int inserted = insertWatchListCodeCommand.ExecuteNonQuery(); 

GetVwdCodeRecords रिटर्न IEnumerable<SqlDataRecord>:

यह जहां मैं इसका इस्तेमाल ADO.NET कोड है।


धन्यवाद सब कुछ। यदि भविष्य के पाठक को यह जानने में दिलचस्पी है कि मैंने सॉर्ट-ऑर्डर की गारंटी कैसे दी है। के रूप में एक और कॉलम जोड़ कर सुझाव दिया मैं तालिका प्रकार modifed गया है:

CREATE TYPE [dbo].[VwdCodeList] AS TABLE(
    [VwdCode] [varchar](50) NOT NULL, 
    [Sort] [smallint] NOT NULL 
) 

डालने-एसक्यूएल और भी आसान है क्योंकि तरह-स्तंभ में पारित हो जाता है और गणना नहीं है:

public const string InsertWatchListCodes = @" 
INSERT INTO [dbo].[WatchListCodes] 
    ([WatchListID] 
    ,[VwdCode] 
    ,[Sort]) 
SELECT @WatchListID, cl.VwdCode, cl.Sort 
FROM @VwdCodeList cl;"; 

के लिए

public static IEnumerable<SqlDataRecord> GetVwdCodeRecords(IEnumerable<string> vwdCodes, bool trimCode = true) 
{ 
    short currentSort = 0; 
    foreach (string vwdCode in vwdCodes) 
    { 
     var record = new SqlDataRecord(
      new SqlMetaData("VwdCode", SqlDbType.VarChar, 50), 
      new SqlMetaData("Sort", SqlDbType.SmallInt)); 
     record.SetString(0, trimCode ? vwdCode.Trim() : vwdCode); 
     record.SetInt16(1, ++currentSort); 

     yield return record; 
    } 
} 
+0

द्वारा स्पष्ट आदेश का उल्लेख न करें, संभावना है कि यह तालिका प्रकार परिभाषा पर निर्भर करता है। उदाहरण के लिए, अपने टेबल प्रकार पर प्राथमिक कुंजी को परिभाषित करने के क्रम में उस क्रम को बदलने का एक अच्छा मौका है जिसमें आपको अपने रिकॉर्ड वापस मिलते हैं। मैं तालिका प्रकार में एक और कॉलम जोड़ने और इसे अपने ADO.NET कोड में सेट करने का एक सुरक्षित दृष्टिकोण लेगा। – dasblinkenlight

उत्तर

3

सामान्य में: पूर्णता के लिए, यहाँ विधि देता है कि IEnumerable<SqlDataRecord> तालिका-मान-पैरामीटर (छोड़े गए त्रुटि हैंडलिंग) के लिए मूल्य के रूप में प्रयोग किया जाता है पर किसी भी परिणाम सेट पर कोई अंतर्निहित सॉर्ट ऑर्डर नहीं है।

रास्ता केवल एक गारंटी सॉर्ट क्रम बाहरी सबसे क्वेरी पर एक ORDER BY है प्राप्त करने के लिए।

मुझे यकीन है कि आप इस पहले से ही पता था कि हूँ ...

वहाँ एक specialty with ROW_NUMBER() OVER(ORDER BY ...) Read "General Remarks" है। लेकिन यह खतरनाक है।

  • सॉर्ट-ऑर्डर केवल तभी सुनिश्चित है, यदि आप ORDER BY में एक अद्वितीय प्रकार का मानदंड उपयोग कर रहे हैं। आप SELECT 1 का उपयोग कर रहे हैं, जो किसी भी क्रम क्रम की गारंटी नहीं देगा। यह सैकड़ों परीक्षणों का काम कर सकता है और अचानक टूट सकता है ...
  • कोई भी बाद की कार्रवाई इस तरह के क्रम को नष्ट कर सकती है। बस कल्पना करें कि आपके पास एक कार्यशील कार्य है और कुछ महीने बाद - आप इस फ़ंक्शन को जटिल क्वेरी में उपयोग करते हैं।

मैं एक्सएमएल के भीतर एक निश्चित आदेश के साथ उदाहरण बनाने के लिए इसका उपयोग करता हूं, क्योंकि एक्सएमएल के भीतर स्थिति द्वारा दिया गया एक निहित आदेश है ...

1

हां, आपको एक कॉलम जोड़ने की आवश्यकता है। एसक्यूएल एक सेट-आधारित भाषा है और सेट स्वाभाविक रूप से अनियंत्रित हैं (स्वीकार्य रूप से, कुछ मामलों से अधिक हैं जहां एसक्यूएल इस बारे में कमजोर है)।

आप ORDER BY उपयोग करना चाहते हैं और आप परिणाम की गारंटी चाहते हैं, आप यह सुनिश्चित करना है कि यह डेटा तालिका के अंदर ऐसी है कि वह विशिष्ट आदेश को परिभाषित करता है के आधार पर पर्याप्त भाव पर आधारित है की जरूरत है। यहां, आप निरंतर आदेश दे रहे हैं (और आपको प्राप्त होने वाली चेतावनियां यदि आप केवल ORDER BY 1 आज़माएं तो यहां पर्याप्त सुराग होना चाहिए कि यह अच्छी तरह से काम नहीं करेगा) इसलिए वास्तव में ऑर्डरिंग पर कोई गारंटी नहीं है।

+0

धन्यवाद। लेकिन क्या यह नहीं हो सकता कि तालिका-मूल्यवान-पैरामीटर के लिए उपयोग किया जाने वाला एक कस्टम टेबल-प्रकार एसक्यूएल-सर्वर द्वारा अलग-अलग व्यवहार किया जाता है? ताकि वे वास्तव में सम्मिलन आदेश को वही बने रहने की गारंटी दें। यह उपयोगी होगा। मुझे पता है कि आदेश सामान्य रूप से गारंटी नहीं है और एक तालिका में "अंतर्निहित" आदेश नहीं है। लेकिन एक टेबल-प्रकार जिसमें पैरामीटर के रूप में बहुत कम जीवनकाल होता है और अलग-अलग व्यवहार कर सकता है। लेकिन मुझे लगता है कि एक सादे टेबल में कोई अंतर नहीं है। –

+1

@TimSchmelter - उस बिंदु पर जिस समय टेबल-प्रकार पेश किए गए थे, प्रत्येक अनुभवी एसक्यूएल डेवलपर का उपयोग टेबल के साथ काम करने के लिए किया जाता था जिसमें कोई अंतर्निहित आदेश नहीं होता था। तो, इन नई वस्तुओं के लिए अतिरिक्त गारंटी या विकास प्रयास प्रदान करने का औचित्य क्या होगा, ताकि वे अलग-अलग कार्य कर सकें? और यदि उनके पास यह आश्चर्यजनक नया व्यवहार था, तो आप इस सुविधा के हिस्से के रूप में प्रलेखन में हाइलाइट होने की उम्मीद करेंगे। –

1

एक ही आदेश की गारंटी है नहीं जब तक आप द्वारा एक स्पष्ट आदेश कर ..

नीचे कुछ परीक्षण कर रहे हैं ..

create type numbes as table 
(
num int primary key 
) 


DECLARE @nums AS numbes; 

insert into @nums 
select row_number() over(order by(select 1)) 
from 
master.sys.objects 


select Top 100* from @nums 

और कार्य योजना लागू करके पता चलता ..

enter image description here

तो कोड के टुकड़े के नीचे ..

ROW_NUMBER()OVER(ORDER BY (SELECT 1)) 
FROM @VwdCodeList;"; 

आपको हर बार एक ही आदेश नहीं मिल सकता है, जब तक कि आप

+0

धन्यवाद। लेकिन क्या यह नहीं हो सकता कि तालिका-मूल्यवान-पैरामीटर के लिए उपयोग किया जाने वाला एक कस्टम टेबल-प्रकार एसक्यूएल-सर्वर द्वारा अलग-अलग व्यवहार किया जाता है? ताकि वे वास्तव में वही बने रहने के लिए प्रविष्टि आदेश _guarantee_। यह उपयोगी होगा। मुझे पता है कि आदेश सामान्य रूप से गारंटी नहीं है और एक तालिका में "अंतर्निहित" आदेश नहीं है। लेकिन एक टेबल-प्रकार जिसमें पैरामीटर के रूप में बहुत कम जीवनकाल होता है और अलग-अलग व्यवहार कर सकता है। आपके उदाहरण में आप एक सादे तालिका से चयन कर रहे हैं। –

+0

मैंने टेबल वैल्यू पैरामीटर के लिए भी यही सोचा था, क्योंकि वे केवल पढ़ रहे हैं .. लेकिन ऑर्डर द्वारा किसी भी परिणाम सेट के लिए गारंटी नहीं है, जब तक आप ऑर्डर नहीं करते .. आप भी इस लेख को देखना चाहेंगे .. – TheGameiswar

+0

https: // ब्लॉग .msdn.microsoft.com/conor_cunningham_msft/2008/08/27/no-seatbelt-expecting-order-without-order-by/ – TheGameiswar

संबंधित मुद्दे