Para Nvarchar (Max) estou recebendo apenas 4000 caracteres no TSQL?

Isto é para o SS 2005.

Por que eu estou recebendo apenas 4000 caracteres e não 8000?

Ele trunca a string @ SQL1 em ​​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 

Você declarou isso como nvarchar (max), que permite 2 GB de dados para que ele armazene 2 GB.

O que está acontecendo:

  • O tipo de dados ainda não é nvarchar (max) até a designação para @ sql1
  • Antes disso, é uma coleção de strings, cada uma com menos de 4000 ( constantes )
  • Você está concatenando constantes curtas com variables ​​curtas (short = <4000)
  • Então você tem 4000 caracteres colocados em @ sql1

Então, você tem certeza que você tem nvarchar (max) no lado direito.

Uma ideia. A segunda linha concatena nvarchar (max) com uma constante = nvarchar (max)

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

Não é diferente da divisão inteira que acontece em todos os langauge.

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

A precedência do operador (infere a precedência do tipo de dados) é sempre “atribuição” por último … por que as cadeias de caracteres unicode no SQL Server devem ser diferentes?

Atualização : o comentário do gbn está certo, e eu estava errado. Como o MSDN aponta, nvarchar (max) suporta até 2 ^ 31-1 bytes de dados, armazenados como UCS-2 (2 bytes por caractere, mais 2 para BOM). Seu problema parece ser com a concatenação de strings, não com os limites de tipo de dados.

Dito isto, se você estiver usando para construir uma string SQL, por que não usar VARCHAR? Você tem nomes de campo que não podem ser representados pelo conjunto de caracteres nativos do database (geralmente Latin-1)?

Finalmente – você poderia simplificar todo o seu problema simplesmente não usando SQL dynamic em seu procedimento armazenado. Crie algumas funções com valor de tabela que usem as strings de cláusula where e as tabelas de retorno e, em seguida, apenas JOIN-AS no procedimento. Como bônus, quase certamente será muito mais rápido, já que pelo menos o database poderá armazenar em cache o corpo do SP como uma declaração preparada.

Eu resolver problema apenas include o caractere N antes de cada seqüência e problema resolvido por exemplo

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

devemos ser

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

se você definir string para vazio também deve definir N ”

 if @where is null set @where = N'' 

🙂 resposta simples

    Intereting Posts