2011-10-20 14 views
8

मैंने कई बार पढ़ और सुना है कि sql_variant से बचा जाना चाहिए। मुझे लगता है कि इसके लिए मेरे पास बहुत अच्छा उपयोग है। मैंने अतीत में varchar(max) का उपयोग उसी कॉलम में विभिन्न प्रकारों को स्टोर करने के लिए किया है, लेकिन ऐसा लगता है कि एक अंतर्निहित प्रकार है जो वास्तव में वही है जो डी/सीरियलाइजेशन ओवरहेड से बचने के लिए समझदार लगता है।sql_variant का उपयोग करने के नुकसान क्या हैं?

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

+0

आप एक ही कॉलम में विभिन्न प्रकार क्यों संग्रहीत कर रहे हैं? क्या यह एक 'ईएवी' संरचना है? –

+0

नहीं। मैं वास्तव में अपने उपयोग के मामले की वैधता के साथ छेड़छाड़ नहीं करना चाहता हूं, लेकिन मेरे पास फ़िल्टर की एक तालिका है जिसे विभिन्न कॉलम पर लागू किया जा सकता है। इस प्रकार तुलनात्मक मूल्य विभिन्न प्रकार के होते हैं। – Daniel

उत्तर

0

दिमाग में आने वाला एकमात्र स्पष्ट गड़बड़ ऐसी स्थितियों में है जहां आपके पास मूल्य है जो आप अपने sql_variant फ़ील्ड में धक्का देना चाहते हैं जो इसकी अधिकतम लंबाई (8016 बाइट्स, इस वेब पेज के अनुसार) http://msdn.microsoft.com/en-us/library/ms173829.aspx) से अधिक है। यदि आपके मूल्य उस सीमा तक कभी नहीं पहुंचते हैं, तो sql_variant एक बहुत अच्छा दृष्टिकोण हो सकता है। अन्यथा, आप अभी भी sql_variant का उपयोग कर सकते हैं, लेकिन एक अलग "isBlob" बिट फ़ील्ड प्रदान करते हैं जो आपके varbinary (अधिकतम) मानों (उदाहरण के लिए) के साथ एक अलग तालिका को इंगित करता है।

आप इस क्षेत्र का उपयोग अधिकांश समय, आप प्रकार (का उपयोग कर sql_variant_property) की जाँच करने के लिए जा रहे हैं:

1

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

आपको हर बार जब आप इसका उपयोग करते हैं, तो आपको इस क्षेत्र को भी डालना होगा, जिससे आगे प्रदर्शन जुर्माना होगा।

आगे, sql_variant कॉलम प्राथमिक कुंजी का हिस्सा नहीं हो सकते हैं, वे एक गणना कॉलम के हिस्से के रूप में काम नहीं करते हैं, और वे WHERE खंड में LIKE के साथ काम नहीं करते हैं।

1

यह प्रोग्रामिंग त्रुटियों के लिए भी आसान बनाता है। एक डीबीए/प्रोग्रामर एक कॉलम को देखता है और यह एक पूर्णांक की तरह दिखता है, इसलिए वह इसमें एक पूर्णांक डालता है, लेकिन रेखा से आगे एक प्रक्रिया चाहता है कि एक स्ट्रिंग बनना चाहें। मैंने इसे sql_variant कॉलम में खराब लिखित आयात के साथ देखा है।

1

SQL_VARIANT के माध्यम से उसी कॉलम में विभिन्न प्रकारों को संग्रहीत करना लगभग सभी चीजों को Object पर .NET में कास्टिंग करने जैसा ही है। और कभी-कभी इस प्रकार का उपयोग करने के वैध कारण हैं क्योंकि यह निश्चित रूप से अधिक सामान्य प्रोग्रामेटिक संरचना की अनुमति दे सकता है।

  1. बस Object के लिए सब कुछ कास्टिंग की तरह:

    लेकिन, जैसा कि आप की आशंका कर रहे थे, वहाँ SQL_VARIANT उपयोग करने के लिए कुछ नुकसान है कि आप के बारे में पता होना चाहिए, विशेष रूप से के रूप में उनमें से एक एक सौदा ब्रेकर हो सकता है कर रहे हैं .NET में (और संभवतः आधार प्रकार के आधार पर मुक्केबाजी/अनबॉक्सिंग की आवश्यकता होती है), SQL_VARIANT का उपयोग करते समय एक निश्चित प्रदर्शन हिट होता है। उपयोग के मामले के आधार पर, कार्यक्षमता को कम करने के लिए स्वीकार्य हो सकता है यदि कार्यक्षमता को वास्तव में इसकी आवश्यकता होती है और/या उपयोग बहुत बार नहीं होता है (यानि प्रति सेकंड कई बार)।

  2. .NET में Object पर सबकुछ कास्टिंग करने के विपरीत, SQL_VARIANT डेटाटाइप में आधारभूत डेटापैप्स में सीमाएं हैं।निम्नलिखित डेटाटाइप्स SQL_VARIANT के रूप में जमा नहीं किया जा सकता:

    • VARCHAR(MAX)
    • NVARCHAR(MAX)
    • VARBINARY(MAX)
    • XML
    • TIMESTAMP/ROWVERSION
    • TEXT (आप के रूप में वैसे भी इस प्रकार का उपयोग नहीं किया जाना चाहिए एसक्यूएल सर्वर 2005)
    • NTEXT
    • IMAGE (आप इस प्रकार का उपयोग नहीं किया जाना चाहिए वैसे भी SQL सर्वर 2005 के रूप में)

    यह सीमा आसानी से रोका जा सकता है (यदि आप नहीं इस प्रकार वैसे भी SQL सर्वर 2005 के रूप में प्रयोग किया जाना चाहिए) यदि इनमें से किसी भी डेटाटाइप को स्टोर करने की आवश्यकता है तो SQL_VARIANT का उपयोग करने की संभावना। ,

    Msg 206, Level 16, State 2, Line 2 
    Operand type clash: varchar(max) is incompatible with sql_variant 
    

निष्पक्ष बनाने के लिए एक: कृपया ध्यान दें कि यहां मुद्दा यह है, आधार डेटाप्रकार और नहीं डेटा के आकार है के रूप में निम्नलिखित परीक्षण पता चलता है:

DECLARE @tmp1 TABLE (col1 SQL_VARIANT NOT NULL); 
INSERT INTO @tmp1 (col1) VALUES (CONVERT(VARCHAR(MAX), 'g')); 

रिटर्न का उपयोग NVARCHAR पर सबकुछ कास्टिंग करने के लिए SQL_VARIANT अंतर्निहित प्रकार की जानकारी को बरकरार रखता है और इसके उपयोग को लागू करता है ताकि आप आसानी से अनुचित संदर्भों में मूल्यों का आसानी से दुरुपयोग नहीं कर सकें।

DECLARE @tmp2 TABLE (col1 SQL_VARIANT NOT NULL); 
INSERT INTO @tmp2 (col1) VALUES (1); 

SELECT CONVERT(DATETIME, col1) FROM @tmp2; 

SELECT CONVERT(TIME, col1) FROM @tmp2; 

रिटर्न:

1900-01-02 00:00:00.000 

Msg 529, Level 16, State 3, Line 6 
Explicit conversion from data type int to time is not allowed. 

एक पी के रूप में SQL_VARIANT उपयोग करने में सक्षम नहीं किया जा रहा बारे में: यह वास्तव में एक सामान्य डेटाप्रकार के स्वभाव के बाद से एक गैर मुद्दा है काफी में वांछनीय होने से शामिल नहीं है इस तरह के उपयोग के लिए पहली जगह।

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

WHERE CONVERT(NVARCHAR(50), [sql_variant_field]) LIKE '%something%' 

उपर्युक्त निश्चित रूप से सबसे कुशल नहीं है, लेकिन यह कार्यात्मक है, और जैसा ऊपर बताया गया है, दक्षता पहले ही अस्वीकार कर दी गई थी क्योंकि SQL_VARIANT डेटाटाइप का उपयोग करने का निर्णय लेने पर कार्यक्षमता के बदले में इसे त्याग दिया गया था।

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