2009-09-03 7 views
10

यह एसएस 2005 के लिए है।Nvarchar (अधिकतम) के लिए मुझे केवल टीएसक्यूएल में 4000 वर्ण मिल रहे हैं?

मुझे केवल 4000 वर्ण क्यों मिल रहे हैं और 8000 नहीं?

यह 4000.

ALTER PROCEDURE sp_AlloctionReport(
    @where NVARCHAR(1000), 
    @alldate NVARCHAR(200), 
    @alldateprevweek NVARCHAR(200)) 
AS 
    DECLARE @SQL1 NVARCHAR(Max) 

    SET @SQL1 = 'SELECT DISTINCT VenueInfo.VenueID, VenueInfo.VenueName, VenuePanels.PanelID, 
    VenueInfo.CompanyName, VenuePanels.ProductCode, VenuePanels.MF, VenueInfo.Address1, 
    VenueInfo.Address2, '' As AllocationDate, '' As AbbreviationCode, VenueInfo.Suburb, VenueInfo.Route, VenueInfo.ContactFirstName, 
    VenueInfo.ContactLastName, VenueInfo.SuitableTime, VenueInfo.OldVenueName, 
    VenueCategories.Category, VenueInfo.Phone, VenuePanels.Location, VenuePanels.Comment, 
    [VenueCategories].[Category] + '' Allocations'' AS ReportHeader, 
    ljs.AbbreviationCode AS PrevWeekCampaign 
    FROM (((VenueInfo INNER JOIN VenuePanels ON VenueInfo.VenueID = VenuePanels.VenueID) 
    INNER JOIN VenueCategories ON VenueInfo.CategoryID = VenueCategories.CategoryID) 
    LEFT JOIN (SELECT CampaignProductions.AbbreviationCode, VenuePanels.PanelID, CampaignAllocations.AllocationDate 
        FROM (((VenueInfo INNER JOIN VenuePanels ON VenueInfo.VenueID=VenuePanels.VenueID) INNER JOIN CampaignAllocations ON VenuePanels.PanelID=CampaignAllocations.PanelID) INNER JOIN CampaignProductions ON CampaignAllocations.CampaignID=CampaignProductions.CampaignID) INNER JOIN VenueCategories ON VenueInfo.CategoryID=VenueCategories.CategoryID 
        WHERE ' + @alldateprevweek + ') ljs 
       ON VenuePanels.PanelID = ljs.PanelID) 
    INNER JOIN (SELECT VenueInfo.VenueID, VenuePanels.PanelID, VenueInfo.VenueName, VenueInfo.CompanyName, VenuePanels.ProductCode, 
       VenuePanels.MF, VenueInfo.Address1, VenueInfo.Address2, CampaignAllocations.AllocationDate, 
       CampaignProductions.AbbreviationCode, VenueInfo.Suburb, VenueInfo.Route, VenueInfo.ContactFirstName, 
       VenueInfo.ContactLastName, VenueInfo.SuitableTime, VenueInfo.OldVenueName, VenueCategories.Category, 
       VenueInfo.Phone, VenuePanels.Location, VenuePanels.Comment, [Category] + '' Allocations'' AS ReportHeader, 
       ljs2.AbbreviationCode AS PrevWeekCampaign 
       FROM ((((VenueInfo INNER JOIN VenuePanels ON VenueInfo.VenueID = VenuePanels.VenueID) 
       INNER JOIN CampaignAllocations ON VenuePanels.PanelID = CampaignAllocations.PanelID) 
       INNER JOIN CampaignProductions ON CampaignAllocations.CampaignID = CampaignProductions.CampaignID) 
       INNER JOIN VenueCategories ON VenueInfo.CategoryID = VenueCategories.CategoryID) 
       LEFT JOIN (SELECT CampaignProductions.AbbreviationCode, VenuePanels.PanelID, CampaignAllocations.AllocationDate 
           FROM (((VenueInfo INNER JOIN VenuePanels ON VenueInfo.VenueID=VenuePanels.VenueID) INNER JOIN CampaignAllocations ON VenuePanels.PanelID=CampaignAllocations.PanelID) INNER JOIN CampaignProductions ON CampaignAllocations.CampaignID=CampaignProductions.CampaignID) INNER JOIN VenueCategories ON VenueInfo.CategoryID=VenueCategories.CategoryID 
           WHERE ' + @alldateprevweek + ') ljs2 
          ON VenuePanels.PanelID = ljs2.PanelID 
       WHERE ' + @alldate + ' AND ' + @where + ') ljs3 
       ON VenueInfo.VenueID = ljs3.VenueID 
    WHERE (((VenuePanels.PanelID)<>ljs3.[PanelID] And 
     (VenuePanels.PanelID) Not In (SELECT PanelID FROM CampaignAllocations WHERE ' + @alldateprevweek + ')) 
     AND ' + @where + ') 
    UNION ALL 
    SELECT VenueInfo.VenueID, VenueInfo.VenueName, VenuePanels.PanelID, VenueInfo.CompanyName, VenuePanels.ProductCode, 
    VenuePanels.MF, VenueInfo.Address1, VenueInfo.Address2, CampaignAllocations.AllocationDate, 
    CampaignProductions.AbbreviationCode, VenueInfo.Suburb, VenueInfo.Route, VenueInfo.ContactFirstName, 
    VenueInfo.ContactLastName, VenueInfo.SuitableTime, VenueInfo.OldVenueName, VenueCategories.Category, 
    VenueInfo.Phone, VenuePanels.Location, VenuePanels.Comment, [Category] + '' Allocations'' AS ReportHeader, 
    ljs.AbbreviationCode AS PrevWeekCampaign 
    FROM ((((VenueInfo INNER JOIN VenuePanels ON VenueInfo.VenueID = VenuePanels.VenueID) 
    INNER JOIN CampaignAllocations ON VenuePanels.PanelID = CampaignAllocations.PanelID) 
    INNER JOIN CampaignProductions ON CampaignAllocations.CampaignID = CampaignProductions.CampaignID) 
    INNER JOIN VenueCategories ON VenueInfo.CategoryID = VenueCategories.CategoryID) 
    LEFT JOIN (SELECT CampaignProductions.AbbreviationCode, VenuePanels.PanelID, CampaignAllocations.AllocationDate 
        FROM (((VenueInfo INNER JOIN VenuePanels ON VenueInfo.VenueID=VenuePanels.VenueID) INNER JOIN CampaignAllocations ON VenuePanels.PanelID=CampaignAllocations.PanelID) INNER JOIN CampaignProductions ON CampaignAllocations.CampaignID=CampaignProductions.CampaignID) INNER JOIN VenueCategories ON VenueInfo.CategoryID=VenueCategories.CategoryID 
        WHERE ' + @alldateprevweek + ') ljs 
       ON VenuePanels.PanelID = ljs.PanelID 
    WHERE ' + @alldate + ' AND ' + @where 

    Select @SQL1 
+0

+1, मैंने इसे चर के लिए प्लेसहोल्डर का उपयोग करके हल किया है, और फिर उन्हें प्रतिस्थापित करें। – gotqn

+2

मुझे लगता है कि यह इस प्रश्न का बेहतर उत्तर है: http://stackoverflow.com/questions/12639948/sql-nvarchar-and-varchar-limits – IHTS

+0

@ आईएचटीएस मैं सहमत हूं - मुझे लगता है कि यह बेहतर है अगर उपयोगकर्ता अन्य क्यूए को निर्देशित करें। – whytheq

उत्तर

43

आपने इसे nvarchar (अधिकतम) के रूप में घोषित किया है जो 2 जीबी डेटा की अनुमति देता है ताकि यह 2 जीबी स्टोर करेगा।

क्या हो रहा है:

  • डेटाप्रकार काम @ करने के लिए sql1
  • कि इससे पहले कि जब तक nvarchar (अधिकतम) अभी तक नहीं है, यह तार का एक संग्रह, प्रत्येक कम से कम 4000 (constants)
  • है
  • आप कम चर के साथ लघु स्थिरांक श्रृंखलाबद्ध कर रहे हैं (कम = < 4000)
  • तो तुम 4000 वर्ण
  • sql1 @ में डाल दिया है

तो, आपने सुनिश्चित किया है कि आपके पास दाएं हाथ पर nvarchar (अधिकतम) है।

एक विचार। 2 लाइन संयोजित करता है nvarchar एक निरंतर = nvarchar (अधिकतम) के साथ (अधिकतम)

SET @SQL1 = '' 
SET @SQL1 = @SQL1 + 'SELECT DISTINCT Venue... 
    .... 

यह पूर्णांक विभाजन है कि हर भाषा के में क्या होता है के लिए अलग नहीं है।

declare @myvar float 
set @myvar = 1/2 --gives zero because it's integer on the right 

ऑपरेटर पूर्वता (infers डेटाप्रकार पूर्वता) हमेशा पिछले है "काम" ... क्यों यूनिकोड चाहिए एसक्यूएल सर्वर में तार किसी भी अलग अलग हो सकता है?

+1

+1। मैं जोड़ना चाहता हूं, आपके पास 8000 से अधिक वर्चर (अधिकतम) या 4000 nvarchar (अधिकतम) की एक स्ट्रिंग स्थिरता हो सकती है। लेकिन अगर वे 8000/4000 से कम हैं तो वे अधिकतम विविधता नहीं होंगे। –

+0

+1 लेकिन मैं यह बहुत मूर्खतापूर्ण पाया जा रहा हूं। मान लें कि एमएस के लिए ठीक है, अगर आपको इसकी आवश्यकता नहीं है, तो इसका उपयोग/आवंटित (MAX) आकार का कोई मतलब नहीं है, लेकिन जब आपको इसकी आवश्यकता होती है (उदाहरण के लिए उपर्युक्त मामला, जो मेरा मामला भी है) यह मेरे लिए बेवकूफ है स्ट्रिंग काटने के लिए। – gotqn

4

अद्यतन में स्ट्रिंग @ SQL1 ट्रंकेटस: gbn's comment सही है, और मैं गलत था। MSDN अंक के रूप में, nvarchar (max) डेटा के 2^31-1 बाइट्स का समर्थन करता है, जिसे यूसीएस -2 (प्रति बाइट 2 बाइट, बीओएम के लिए 2) के रूप में संग्रहीत किया जाता है। आपकी समस्या स्ट्रिंग concatenation के साथ प्रतीत होता है, डेटा प्रकार सीमा नहीं।

उसने कहा, यदि आप इसे SQL स्ट्रिंग बनाने के लिए उपयोग कर रहे हैं, तो VARCHAR का उपयोग क्यों न करें? क्या आपके पास फ़ील्ड नाम हैं जो डेटाबेस के मूल वर्ण सेट (आमतौर पर लैटिन -1) द्वारा प्रदर्शित नहीं होते हैं?

अंत में - आप अपनी संग्रहीत प्रक्रिया में गतिशील एसक्यूएल का उपयोग न करके अपनी पूरी समस्या को सरल बना सकते हैं। कुछ टेबल-मूल्यवान फ़ंक्शंस बनाएं जो आपके कहां-क्लॉज स्ट्रिंग और लौटें टेबल लेते हैं, और फिर बस अपनी प्रक्रिया में शामिल हों। बोनस के रूप में यह लगभग निश्चित रूप से बहुत तेज़ होगा, क्योंकि कम से कम डेटाबेस एसपी बॉडी को एक तैयार कथन के रूप में कैश करने में सक्षम होगा।

+0

यह प्रश्न का उत्तर नहीं देता है: @ sql1 को nvarchar (अधिकतम) के रूप में घोषित किया गया है जो 2 जीबी की अनुमति देता है। – gbn

+0

@ जीबीएन: आप सही हैं, और मैंने अपना जवाब संपादित कर लिया है। मुझे अभी भी लगता है कि तालिका-मूल्यवान कार्यों का उपयोग करना बेहतर समाधान है, हालांकि। –

+0

@ डैनियल: हाँ, या वर्चर, या वास्तविक एसक्यूएल जैसा आपने उल्लेख किया है। दुर्भाग्य से – gbn

0

मैं समस्या हल बस से पहले हर स्ट्रिंग और समस्या उदाहरण के लिए हल एन चरित्र शामिल

declare @sql nvarchar(max) = '' + @Where + 'SomeThing'; 

होना चाहिए

declare @sql nvarchar(max) = N'' + @Where + N'SomeThing'; 

अगर आप भी खाली करने के लिए एन सेट करना होगा ''

स्ट्रिंग सेट
if @where is null 
set @where = N'' 

:-) सरल उत्तर

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