Для Nvarchar (Max) я получаю только 4000 символов в TSQL?
Это для SS 2005.
Почему я только получаю 4000 символов, а не 8000?
Он обрезает строку @SQL1 на 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
Ответы
Ответ 1
Вы объявили это как nvarchar (max), который позволяет получать 2 ГБ данных, поэтому он будет хранить 2 ГБ.
Что происходит:
- Тип данных еще не nvarchar (max) до присвоения @sql1
- До этого он представляет собой набор строк, каждый из которых меньше 4000 (константы)
- Вы объединяете короткие константы с короткими переменными (short = < 4000)
- Итак, у вас 4000 символов, помещенных в @sql1
Итак, вы убедитесь, что у вас есть nvarchar (max) с правой стороны.
Одна идея. Вторая строка объединяет nvarchar (max) с константой = nvarchar (max)
SET @SQL1 = ''
SET @SQL1 = @SQL1 + 'SELECT DISTINCT Venue...
....
Это не отличается от целочисленного деления, которое происходит в каждом langauge.
declare @myvar float
set @myvar = 1/2 --gives zero because it integer on the right
Приоритет оператора (предшествует приоритету datatype) всегда является "назначением" последним... почему строки unicode в SQL Server могут быть разными?
Ответ 2
Обновить: комментарий gbn - это правильно, и я ошибся. Поскольку MSDN указывает, nvarchar (max) поддерживает до 2 ^ 31-1 байт данных, сохраненных как UCS-2 (2 байт на символ, плюс 2 для спецификации). Ваша проблема связана с конкатенацией строк, а не с ограничениями типа данных.
Тем не менее, если вы используете его для построения строки SQL, почему бы не использовать VARCHAR? У вас есть имена полей, которые не могут быть представлены базовым набором символов базы данных (обычно Latin-1)?
Наконец, вы можете упростить всю свою проблему, просто не используя динамический SQL в своей хранимой процедуре. Создайте некоторые табличные функции, которые берут строки where-where и таблицы возврата, а затем просто присоединяются к ним в вашей процедуре. В качестве бонуса это почти наверняка будет намного быстрее, так как по крайней мере база данных сможет кэшировать тело SP как подготовленный оператор.
Ответ 3
i решить проблему
просто включите символ N перед каждой строкой, и проблема решена
например
declare @sql nvarchar(max) = '' + @Where + 'SomeThing';
должен быть
declare @sql nvarchar(max) = N'' + @Where + N'SomeThing';
если вы установили строку в пустую, также необходимо установить N ''
if @where is null
set @where = N''
:-) простой ответ