SQL दृश्य - कोई चर नहीं?


83

क्या किसी दृश्य के भीतर एक चर घोषित करना संभव है? उदाहरण के लिए:

Declare @SomeVar varchar(8) = 'something'

मुझे सिंटैक्स त्रुटि देता है:

कीवर्ड 'डिक्लेयर' के पास गलत सिंटैक्स।

जवाबों:


66

तुम सही हो। किसी दृश्य में स्थानीय चर की अनुमति नहीं है।

आप एक स्थानीय वैरिएबल को टेबल वैल्यू फ़ंक्शन में सेट कर सकते हैं, जो एक परिणाम सेट देता है (जैसे कोई दृश्य करता है।)

http://msdn.microsoft.com/en-us/library/ms191165.aspx

जैसे

CREATE FUNCTION dbo.udf_foo()
RETURNS @ret TABLE (col INT)
AS
BEGIN
  DECLARE @myvar INT;
  SELECT @myvar = 1;
  INSERT INTO @ret SELECT @myvar;
  RETURN;
END;
GO
SELECT * FROM dbo.udf_foo();
GO

क्या इसकी दक्षता एक दृश्य के समान है?
RaRdEvA

नहीं, TVFs अक्सर धीमे होते हैं। "SQL सर्वर के टेबल-वैल्यू फ़ंक्शंस (TVFs) एक अच्छे विचार की तरह प्रतीत होते हैं, लेकिन वे संभावित प्रदर्शन समस्याओं की मेजबानी करते हैं। TVFs धारावाहिक रहने के लिए एक निष्पादन योजना के कुछ हिस्सों का कारण बनते हैं (वे समानता से बचेंगे), वे खराब पंक्ति अनुमान का उत्पादन करते हैं, और मल्टी-स्टेटमेंट TVFs को भी सर्वश्रेष्ठ अनुकूलन उपलब्ध नहीं हो सकता है। संक्षेप में - TVFs की बदबू। " brentozar.com/blitzcache/tvf-join
wp78de

49

आप अपने भावों को परिभाषित करने के लिए उपयोग कर सकते हैं। फिर उन परिभाषाओं तक पहुंचने के लिए एक सरल उप-चयन करें।

CREATE VIEW MyView
AS
  WITH MyVars (SomeVar, Var2)
  AS (
    SELECT
      'something' AS 'SomeVar',
      123 AS 'Var2'
  )

  SELECT *
  FROM MyTable
  WHERE x = (SELECT SomeVar FROM MyVars)

3
यह एक स्थिरांक है, चर नहीं!
व्लादिस्लाव

2
@ व्लादिस्लाव यह आसानी से एक तालिका से डेटा (फ़िल्टर्ड?) डेटा का उपयोग कर सकता है।
डोडेकफोन

18

संपादित करें: मैंने अपने पिछले उत्तर पर एक सीटीई का उपयोग करने की कोशिश की, जो गलत था, जैसा कि @bummi द्वारा बताया गया है। इस विकल्प के बजाय काम करना चाहिए:

इस समस्या के इर्द-गिर्द काम करने के लिए, CROSS APPLY का उपयोग करने का एक विकल्प है:

SELECT st.Value, Constants.CONSTANT_ONE, Constants.CONSTANT_TWO
FROM SomeTable st
CROSS APPLY (
    SELECT 'Value1' AS CONSTANT_ONE,
           'Value2' AS CONSTANT_TWO
) Constants

सुधार के लिए धन्यवाद - इसके बजाय CROSS APPLY का उपयोग करने के लिए अद्यतन किया गया।
डैनियल नील

यह काम करता है, लेकिन क्रॉस के कॉलम को हर पंक्ति के लिए पुनर्निमित नहीं किया जाता है? विशेष रूप से परिकलित मूल्यों के लिए, जिसका अर्थ है एक बड़ा प्रदर्शन नुकसान। यह सिर्फ दुख की बात है कि स्थानीय चर और सीटीई एक दृश्य में उपलब्ध नहीं हैं, किसी को भी एक विचार क्यों?
T_D

1
@T_D आप 'व्यू' में 'CTE' बना और इस्तेमाल कर सकते हैं।
अर्धसत्य

6

@datenstation की सही अवधारणा थी। चर का नाम कैश करने के लिए सीटीई का उपयोग करने वाला एक कार्य उदाहरण यहां दिया गया है:

CREATE VIEW vwImportant_Users AS
WITH params AS (
    SELECT 
    varType='%Admin%', 
    varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers, params
    WHERE status > varMinStatus OR name LIKE varType

SELECT * FROM vwImportant_Users

के माध्यम से भी JOIN

WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers INNER JOIN params ON 1=1
    WHERE status > varMinStatus OR name LIKE varType

के माध्यम से भी CROSS APPLY

WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers CROSS APPLY params
    WHERE status > varMinStatus OR name LIKE varType

4

स्पेंसर7593 के रूप में फ़ंक्शन का उपयोग करना गतिशील डेटा के लिए एक सही दृष्टिकोण है। स्थैतिक डेटा के लिए, एक अधिक प्रदर्शनकारी दृष्टिकोण जो एसक्यूएल डेटा डिज़ाइन (बनाम स्पार्क्स में बड़े पैमाने पर प्रक्रियात्मक कोड को लिखने के विरोधी पैटर्न) के साथ संगत है, स्थैतिक मूल्यों के साथ एक अलग तालिका बनाने और इसमें शामिल होने के लिए है। यह एक प्रॉस्पेक्ट के नजरिए से बेहद फायदेमंद है क्योंकि SQL इंजन एक JOIN के आसपास प्रभावी निष्पादन योजना बना सकता है, और आपको जरूरत पड़ने पर अनुक्रमित जोड़ने की भी क्षमता है।

फ़ंक्शन (या किसी भी इनलाइन परिकलित मान) का उपयोग करने का नुकसान कॉलआउट हर संभावित पंक्ति के लिए होता है , जो महंगा है। क्यों? क्योंकि SQL को पहले परिकलित मानों के साथ एक पूर्ण डेटासेट बनाना होता है और फिर उस डेटासेट पर WHERE क्लॉज लागू करना होता है।

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


3

हां यह सही है, आपके विचारों में परिवर्तन नहीं हो सकते हैं (अन्य प्रतिबंध भी हैं)।

दृश्यों का उपयोग उन मामलों के लिए किया जा सकता है जहां परिणाम को एक चयनित कथन से बदला जा सकता है।


एक टेबल फ़ंक्शन को चुनिंदा स्टेटमेंट में बदला जा सकता है और इसमें स्थानीय चर होते हैं।
जेफ़ो

क्या आप कह रहे हैं कि एक चयनित बयान में स्थानीय चर नहीं हो सकते हैं, एक दृश्य या तो नहीं हो सकता है?
जेफ़ो

1
@ जेफ़ो "आपके विचार में चर नहीं हो सकते हैं" जो मैंने कहा है। क्या यह अस्पष्ट है?
होगन

यह अंतिम वाक्य है। एक दृश्य एक चुनिंदा कथन को बदल सकता है लेकिन चर के साथ क्या करना है? तालिका फ़ंक्शन एक चयनित कथन को प्रतिस्थापित नहीं कर सका, लेकिन चर शामिल हैं?
जेएफओ

1
एक टेबल फ़ंक्शन को एक चयनित स्टेटमेंट के साथ भी बदला जा सकता है, लेकिन टेबल फ़ंक्शंस का उपयोग हर जगह नहीं किया जा सकता है जो एक दृश्य, जैसे कि जुड़ सकते हैं। वह जो कहना चाह रहा है वह यह है कि एक दृश्य एक एकल चुनिंदा कथन को प्रतिस्थापित कर सकता है, लेकिन कई बयानों को प्रतिस्थापित नहीं कर सकता है। BEGIN कीवर्ड क्रिएट व्यू स्टेटमेंट में अमान्य है, साथ ही एक इनलाइन फ़ंक्शन भी है। एक बहुस्तरीय स्क्रिप्ट बनाने की जरूरत होगी। कार्यविधियाँ या कई कथन फ़ंक्शंस संभवतः ऐसा करने का सबसे अच्छा तरीका है।
अर्लीन बीलर

1

मैं जो करता हूं वह एक ऐसा दृश्य बनाता है जो तालिका चर के समान चयन करता है और उस दृश्य को दूसरे दृश्य में लिंक करता है। तो एक दृश्य दूसरे दृश्य से चयन कर सकता है। यह उसी परिणाम को प्राप्त करता है


2
बेन, यह संभवतः एक प्रदर्शन समस्या का कारण होगा जब तक आप बहुत छोटी तालिकाओं के साथ काम नहीं कर रहे हैं।
Logixologist

यहां तक ​​कि बहुत छोटी तालिका (3 रिकॉर्ड) के साथ, लाख रिकॉर्ड वाला एक दृश्य बड़े प्रदर्शन के मुद्दों का कारण बनता है।
st_stefanov

0

आपको कितनी बार दृश्य को ताज़ा करने की आवश्यकता है? मेरे पास एक समान मामला है जहां नया डेटा महीने में एक बार आता है; फिर मुझे इसे लोड करना होगा, और लोडिंग प्रक्रियाओं के दौरान मुझे नए टेबल बनाने होंगे। उस पल में मैंने परिवर्तनों पर विचार करने के लिए अपना दृष्टिकोण बदल दिया। मैंने इस अन्य प्रश्न में आधार की जानकारी का उपयोग किया:

गतिशील और समानार्थी देखें

वहाँ, इसे 2 तरीकों से करने का प्रस्ताव है:

  1. समानार्थी शब्द का उपयोग कर।
  2. दृश्य बनाने के लिए गतिशील SQL का उपयोग करना (यह वही है जिसने मुझे अपना परिणाम प्राप्त करने में मदद की)।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.