2009-10-19 6 views
17

मेरे संग्रहीत प्रक्रिया लगता है:मैं इसे एक बार इस्तेमाल करने के बाद अपने सीटीई का उपयोग क्यों नहीं कर सकता?

WITH MYCTE(....) 
AS 
(
... 
) 

UPDATE ... (using my CTE) 



DELETE (using my CTE) <--- says the object, my CTE, doesn't exist 

मैं केवल एक बार इस्तेमाल कर सकता हूँ?

+0

यह एक अच्छा उदाहरण है कि हम सभी को हमारे टी-एसक्यूएल में सेमीकॉलन का उपयोग क्यों करना चाहिए। अद्यतन के बाद सही ढंग से रखा गया है और हटाए गए बयानों से यह स्पष्ट हो जाता है कि सीटीई UPDATE स्टेटमेंट का _part है। – NReilingh

उत्तर

19

आपके उदाहरण कोड में, सीटीई केवल अद्यतन के लिए जारी रहता है। यदि आपको इसे लंबे समय तक रहने की आवश्यकता है, तो इसके साथ #tempTable या @tableVariable पॉप्युलेट करने पर विचार करें, और फिर उनसे अद्यतन करें और हटाएं।

आप OUTPUT खंड का उपयोग करने के लिए अपने अपडेट को भी बढ़ा सकते हैं, जैसे कि आप प्रभावित पंक्तियों को कैप्चर कर सकते हैं। और यहाँ की तरह हटाएं उन्हें इस्तेमाल,:

set nocount on 
DECLARE @Table  table (PK int, col1 varchar(5)) 
DECLARE @SavedPks table (PK int) 

INSERT INTO @Table VALUES (1,'g') 
INSERT INTO @Table VALUES (2,'g') 
INSERT INTO @Table VALUES (3,'g') 
INSERT INTO @Table VALUES (4,'g') 
INSERT INTO @Table VALUES (5,'x') 
INSERT INTO @Table VALUES (6,'x') 
set nocount off 

;WITH MYCTE 
AS 
(
    SELECT PK, col1 FROM @Table 
) 
UPDATE MYCTE 
    SET col1='xyz' 
    OUTPUT INSERTED.PK 
     INTO @SavedPks 
    WHERE col1='g' 

SELECT 'A',* FROM @Table 

DELETE @Table 
    WHERE PK IN (SELECT PK from @SavedPks) 

SELECT 'B',* FROM @Table 

उत्पादन:

(4 row(s) affected) 
    PK   col1 
---- ----------- ----- 
A 1   xyz 
A 2   xyz 
A 3   xyz 
A 4   xyz 
A 5   x 
A 6   x 

(6 row(s) affected) 

(4 row(s) affected) 

    PK   col1 
---- ----------- ----- 
B 5   x 
B 6   x 

(2 row(s) affected) 
+1

ग्रेट उत्तर। मैं वर्षों से SQL सर्वर का उपयोग कर रहा हूं और आपको नहीं पता था कि आप आउटपुट कर सकते हैं। यह निश्चित रूप से भविष्य में काम में आ जाएगा। – WesleyJohnson

3

एक सीटीई अभिव्यक्ति केवल अपने शरीर में मान्य है। यदि आप इसे अन्य स्थानों पर उपयोग करना चाहते हैं, तो आपको WITH खंड दोहराया जाना चाहिए।

WITH MYCTE(....) AS (...) 
UPDATE ... (using my CTE); 
-- a semicolon is necessary for statements followed by a CTE declaration 

WITH MYCTE(....) AS (...) 
DELETE (using my CTE); 
+0

लेकिन यह अद्यतन में काम कर रहा है, बस डेलेटी में नहीं, क्या यह समझ में आता है? – mrblah

+0

बेशक। 'अद्यतन' आपके सीटीई का शरीर है। –

+0

एएस कीवर्ड के बाद() के अंदर शरीर नहीं है। अद्यतन और हटाएं() के बाहर हैं। – mrblah

3

हाँ, WITH MYCTE खंड एक स्थायी वस्तु नहीं बना रहा है बाद में कई प्रश्नों में उपयोग करने के लिए: यह केवल एक प्रश्न आप के लिए उस खंड जोड़ रहे हैं संशोधित है! यदि आपको बहुत अलग कार्यक्षमता की आवश्यकता है, तो विचारों का उपयोग करके, विचार करें ...

+1

... या temp टेबल (# या @)। –

4

CTE कुछ भी 'असली' न बनाएं। वे केवल भाषा तत्व हैं, एक तालिका अभिव्यक्ति को व्यक्त करने का एक तरीका जिसका उपयोग किया जाएगा, बार-बार संभवतः एक बयान में। जब आप कहते हैं कि

WITH cteFoo AS (select ... from table where ...) 
select ... from cteFoo where ... 

कह

select ... from (select ... from table where ....) as cteFoo where ... 

CTE का एक और तरीका है और व्युत्पन्न टेबल बहुत समान हैं, व्युत्पन्न तालिकाओं का उपयोग किसी भी प्रश्न एक CTE के रूप में rewriten किया जा सकता है, और किसी भी गैर पुनरावर्ती CTE कर सकते हैं व्युत्पन्न तालिकाओं का उपयोग कर एक क्वेरी के रूप में पुनः लिखा जाना चाहिए। निजी तौर पर, मैं सीटीई फॉर्म को और अधिक पसंद करता हूं जैसा कि अधिक संक्षिप्त और पढ़ने में आसान है।

सीटीई की अनुमति देने के एक मेज अभिव्यक्ति के लिए कई बार इस्तेमाल किया केवल एक बार की घोषणा होने के लिए:

WITH cte AS (select ... from table where ...) 
    select ... 
    from cte a join cte b on ... 
    where ... 

शब्दार्थ ली गई तालिका के रूप के साथ इस की तुलना करें:

select ... 
from (
    select ... from table where ...) as a 
join (
    select ... from table where ...) as b 
    on ... 
where ... 

CTE स्पष्ट रूप से अधिक पठनीय है। लेकिन आपको समझना होगा कि दो रूप एक ही प्रश्न का उत्पादन कर रहे हैं। सीटीई फॉर्म सुझाव दे सकता है कि एक मध्यवर्ती परिणाम बनाया गया है, तो मध्यवर्ती परिणाम पर शामिल हो रहा है, लेकिन यह सच नहीं है। सीटीई फॉर्म को व्युत्पन्न तालिका एक के रूप में बिल्कुल उसी रूप में संकलित किया गया है, जो इस तथ्य को स्पष्ट करता है कि सीटीई का तालिका विस्तार दो बार चलाया जाता है।