2012-04-17 8 views
34

मेरे पास यह है, और मुझे कुल सेट पर एक त्रुटि मिलती है। मैं कई बार सीटीई क्यों नहीं पहुंच सकता?कई बार एक सीटीई का उपयोग करें

ALTER PROCEDURE [dbo].[GetLeaguePlayers] 
(
    @idleague int, 
    @pageNumber int, 
    @pageSize int, 
    @total int OUTPUT 
) 
AS 
WITH CTEPlayers AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY p.Name) AS RowNumber, p.Id, p.Name, t.Name AS Team 
    FROM Players p INNER JOIN Teams t ON p.IdTeam=t.Id INNER JOIN Leagues l ON l.Id=t.IdLeague 
    WHERE [email protected] 
) 
SELECT Id, Name 
FROM CTEPlayers c 
WHERE RowNumber>@pageSize*(@pageNumber-1) AND RowNumber<@pageSize*@pageNumber; 
SET @total = (SELECT COUNT(*) FROM CTEPlayers) 
+11

नहीं! *** नहीं ** अपना प्रश्न बदलें! इसके बजाय एक और पूछो। – RBarryYoung

+2

मेरी गलती, मुझे खेद है – gigi

उत्तर

50

CTE मूल रूप से एक डिस्पोजेबल दृश्य है। यह केवल एक ही कथन के लिए बनी रहती है, और फिर स्वचालित रूप से गायब हो जाती है।

आपके विकल्प शामिल हैं:

  • CTE दूसरी बार पुन: निर्धारित करें। यह आपके SET से पहले परिभाषा के अंत के माध्यम से WITH... से कॉपी-पेस्ट जितना आसान है।

  • एक #temp तालिका में अपने परिणाम रखो या एक @table चर

  • एक असली मेज और संदर्भ में परिणाम मटेरियलाइज़ कि

  • ऑल्टर सिर्फ SELECT COUNT अपने CTE से थोड़ा:

SELECT @total = COUNT(*) 
FROM Players p 
INNER JOIN Teams t 
    ON p.IdTeam=t.Id 
INNER JOIN Leagues l 
    ON l.Id=t.IdLeague 
WHERE [email protected] 
+7

सीटीई एक ही क्वेरी तक सीमित नहीं हैं, लेकिन एक ही कथन के लिए। आप एक ही सीटीई (यदि नेस्टेड, अन्य सीटीई आदि में) का उपयोग कर कई प्रश्न पूछ सकते हैं। – Lucero

+1

@ लुसेरो मुझे लगता है कि आप "क्वेरी" की परिभाषा को चुन रहे हैं ... –

+0

@AaronBertrand उसके पास एक बिंदु है, हालांकि। मैं इसे सही कर दूंगा। – JNK

11

एक सीटीई प्रति परिभाषा है, केवल एक कथन के लिए मान्य है।

आप inline table-valued function बना सकते हैं और फिर जितनी बार चाहें इसका उपयोग कर सकते हैं। इनलाइन फ़ंक्शन करता है जो नाम सुझाता है; इसकी क्वेरी का उपयोग करके क्वेरी का हिस्सा बन जाता है (गैर-इनलाइन फ़ंक्शंस के विपरीत जो अलग से निष्पादित होते हैं और एक पंक्ति के रूप में उपयोग किए जाते हैं)।

+0

एक सॉफ्टवेयर डेवलपर के रूप में, मैं इस दृष्टिकोण को पसंद करता हूं। यह मुझे अपने तर्क को एक समारोह में समेकित करने की अनुमति देता है और फिर इसे कई संग्रहीत प्रक्रियाओं में उपयोग करता है। यह जटिल प्रश्नों के लिए विशेष रूप से सहायक है। मैंने पाया है कि मैं स्तंभों का एक गुच्छा वापस कर सकता हूं और इसे पुन: प्रयोज्य बनाने के लिए बहुत से जोड़ों को जोड़ सकता हूं, हालांकि इसके संदर्भ में प्रत्येक स्पोक के लिए आवश्यक नहीं हो सकता है, लेकिन एसक्यूएल-सर्वर अतिरिक्त जोड़ों और कॉलम को संसाधित न करने पर ध्यान रखता है यदि आपका sproc उनका उपयोग नहीं कर रहा है। आपके पास आईटीवीएफ (इनलाइन टेबल-वैल्यूएड फ़ंक्शंस) भी आईटीवीएफ को कॉल कर सकता है ताकि आप अपने बेस क्वेरी तर्क को और भी आगे बढ़ा सकें! – MikeTeeVee

0

इस मामले में, मैं इस का उपयोग करें: ऊपर जवाब में से

ALTER PROCEDURE [dbo].[GetLeaguePlayers] 
(
@idleague int, 
@pageNumber int, 
@pageSize int, 
@total int OUTPUT 
) 
AS 

WITH CTEPlayers AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY p.Name) AS RowNumber,  
     COUNT(1) OVER() AS RecordCount, 
    p.Id, p.Name, 
    t.Name AS Team 
    FROM Players p 
     INNER JOIN Teams t ON p.IdTeam=t.Id 
     INNER JOIN Leagues l ON l.Id=t.IdLeague 
    WHERE [email protected] 
) 

SELECT RowNumber, 
    CAST(CEILING(CAST(RecordCount AS FLOAT)/CAST(@pageSize AS FLOAT)) AS INT) PageCount, 
    RecordCount, 
    Id, 
    Name 
FROM CTEPlayers c 
WHERE RowNumber > @pageSize*(@pageNumber-1) AND RowNumber < @pageSize*@pageNumber; 
8

कोई नहीं कर रहे हैं सही ... आप CTE एक बार निष्पादित और परिणाम आप चाहते हैं प्राप्त कर सकते हैं .. क्वेरी यहां है

ALTER PROCEDURE [dbo].[GetLeaguePlayers] 
(
    @idleague int, 
    @pageNumber int, 
    @pageSize int, 
    @total int OUTPUT 
) 
AS 
WITH CTEPlayers AS 
(
    SELECT p.Id, p.Name, t.Name AS Team 
    FROM Players p INNER JOIN Teams t ON p.IdTeam=t.Id INNER JOIN Leagues l ON l.Id=t.IdLeague 
    WHERE [email protected] 
), 
TotalCount AS 
(
SELECT COUNT(*) AS Total FROM CTEPlayers 
), 
Final_Result AS 
(
SELECT ROW_NUMBER() OVER (ORDER BY p.Name) AS RowNumber, p.Id, p.Name, t.Name AS Team, 
    (SELECT Total FROM TotalCount) AS Total 
    FROM CTEPlayers 
) 
SELECT Id, Name, @total = Total 
FROM Final_Results c 
WHERE RowNumber>@pageSize*(@pageNumber-1) AND RowNumber<@pageSize*@pageNumber; 
+0

ऐसा लगता है कि यह केवल पढ़ने के लिए ही सीमित है। एक ही परिणाम सेट को अपडेट करने का प्रयास करने से मुझे पहले सीटीई के साथ जुड़ने के आधार पर वैध अद्यतन कथन पर त्रुटियां मिल रही हैं। –

+0

मुझे यह त्रुटि ऐसा करने में मिलती है: "एक चयन कथन जो एक चर को मान निर्दिष्ट करता है उसे डेटा-पुनर्प्राप्ति संचालन के साथ जोड़ा जाना चाहिए।" हालांकि एसक्यूएल सर्वर 2014। – user1829319

+0

इसका वास्तव में एसक्यूएल सर्वर 2016 है – user1829319