mensaje - Para Nvarchar(Max) solo estoy obteniendo 4000 caracteres en TSQL?
varchar max length sql server (3)
Usted ha declarado esto como nvarchar (max), que permite 2 GB de datos, por lo que almacenará 2 GB.
Que esta pasando:
- El tipo de datos todavía no es nvarchar (max) hasta la asignación a @ sql1
- Antes de eso, es una colección de cadenas, cada una de menos de 4000 ( constantes )
- Concatenan constantes cortas con variables cortas (short = <4000)
- Entonces tienes 4000 caracteres puestos en @ sql1
Por lo tanto, debe asegurarse de tener nvarchar (max) en el lado derecho.
Una idea. La 2ª línea concatena nvarchar (max) con una constante = nvarchar (max)
SET @SQL1 = ''''
SET @SQL1 = @SQL1 + ''SELECT DISTINCT Venue...
....
No es diferente de la división entera que ocurre en cada lengua.
declare @myvar float
set @myvar = 1/2 --gives zero because it''s integer on the right
La precedencia del operador (infiere la prioridad del tipo de datos) siempre es "asignación" al último ... ¿por qué las cadenas unicode en SQL Server deberían ser diferentes?
Esto es para SS 2005.
¿Por qué solo obtengo 4000 caracteres y no 8000?
Trunca la cadena @ SQL1 en 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
Resuelvo el problema simplemente incluya el carácter N antes de cada cadena y problema resuelto, por ejemplo
declare @sql nvarchar(max) = '''' + @Where + ''SomeThing'';
debe ser
declare @sql nvarchar(max) = N'''' + @Where + N''SomeThing'';
si configura cadena para vaciar también debe establecer N ''''
if @where is null
set @where = N''''
:-) respuesta simple
Actualización : el comentario de gbn es correcto, y estaba equivocado. Como señala MSDN , nvarchar (max) admite hasta 2 ^ 31-1 bytes de datos, almacenados como UCS-2 (2 bytes por carácter, más 2 para la lista de materiales). Su problema parece ser la concatenación de cadenas, no los límites de tipo de datos.
Dicho esto, si lo está usando para construir una cadena SQL, ¿por qué no usar VARCHAR? ¿Tiene nombres de campo que no son representables por el conjunto de caracteres nativos de la base de datos (generalmente Latin-1)?
Finalmente, podría simplificar todo su problema simplemente sin usar SQL dinámico en su procedimiento almacenado. Cree algunas funciones con valores de tabla que tomen sus cadenas where-clause y tablas de retorno, y luego ÚNASE a ellas en su procedimiento. Como beneficio adicional, es casi seguro que será mucho más rápido, ya que al menos la base de datos podrá almacenar en caché el cuerpo del SP como una declaración preparada.