#sql #sql-server #tsql #sql-server-2017
#sql #sql-server #tsql #sql-server-2017
Вопрос:
Я объявил SQL1
переменную типа данных varchar(max)
с максимальной длиной 8000
. Я ожидаю, что она будет содержать до 8000
символов, однако в моем сценарии, несмотря на то, что длина строки 5160
, все равно переменная не содержит весь запрос.
DECLARE @SQL1 VARCHAR (8000)
--DECLARE @SQL2 VARCHAR (8000)
SET @SQL1=''
SET @SQL1=
'
UPDATE v
SET v.ValueLoc = (sf.ValueLoc*isnull(sf.FTE,1)*-1), v.FTE = sf.FTE, v.CurrencyLOC = sf.Currency, v.K4_MODIFIED = getDate()
FROM ##STAFF_PLAN_VALUES v
INNER JOIN (
SELECT
dat.Employee_ID, dat.ElementId, dat.SeriesId, dat.Year, dat.Month, dat.Version, dat.Currency, dat.SeriesValidFrom, dat.SeriesValidTo,
convert(numeric(18,2),sum(dat.MonSalRatio)) AS ValueLOC,
convert(numeric(18,2),sum(dat.MonFTE)) AS FTE
FROM (
SELECT
pt3.Employee_ID, pt3.SeriesId, pt3.ElementId, pt3.Year, pt3.Month, pt4.MonSalary, pt4.MonFTE, pt3.Version`enter code here`, pt4.Currency,
pt3.MonthStart, pt3.MonthEnd, pt4.SeriesValidFrom, pt4.SeriesValidTo, pt4.FteSalFrom, pt4.FteSalTo,
(CASE WHEN pt3.MonthStart>pt4.FteSalFrom THEN pt3.MonthStart ELSE pt4.FteSalFrom END) AS ValidFrom,
(CASE WHEN pt3.MonthEnd<pt4.FteSalTo THEN pt3.MonthEnd ELSE pt4.FteSalTo END) AS ValidTo,
cast((DATEDIFF(day,(CASE WHEN pt3.MonthStart>pt4.SeriesValidFrom THEN pt3.MonthStart ELSE pt4.SeriesValidFrom END),(CASE WHEN pt3.MonthEnd<pt4.SeriesValidTo THEN pt3.MonthEnd ELSE pt4.SeriesValidTo END)) 1) AS float)/
cast((DATEDIFF(day,pt3.MonthStart,pt3.MonthEnd) 1) AS float)*pt4.MonSalary AS MonSalRatio,
cast((DATEDIFF(day,(CASE WHEN pt3.MonthStart>pt4.SeriesValidFrom THEN pt3.MonthStart ELSE pt4.SeriesValidFrom END),(CASE WHEN pt3.MonthEnd<pt4.SeriesValidTo THEN pt3.MonthEnd ELSE pt4.SeriesValidTo END)) 1) AS float)/
cast((DATEDIFF(day,pt3.MonthStart,pt3.MonthEnd) 1) AS float)*pt4.MonFTE AS MonFTERatio
FROM (
SELECT v.*,
cast(cast(v.Year AS varchar(4)) ''-'' right(''0'' cast(v.Month AS varchar(2)),2) ''-01'' AS date) AS MonthStart,
dateadd(day,-1,dateadd(month,1,cast(cast(v.Year AS varchar(4)) ''-'' right(''0'' cast(v.Month AS varchar(2)),2) ''-01'' AS date))) AS MonthEnd
FROM ##STAFF_PLAN_VALUES AS v
) AS pt3 INNER JOIN (
SELECT
pt1.Employee_ID, pt1.SeriesID, pt1.ElementId,
pt1.ValidFrom AS SeriesValidFrom,
pt1.ValidTo AS SeriesValidTo,
pt2.StartDate AS FteSalFrom,
pt2.EndDate AS FteSalTo,
pt1.Version, pt1.PLCode, pt1.LegalEntityId,pt1.BusinessUnitId,pt1.DepartmentId,pt1.Currency,pt2.MonFTE,pt2.MonSalary
FROM
##STAFF_PLAN_ELEMENTS AS pt1
INNER JOIN (SELECT C.Employee_ID, C.StartDate, C.Salary, 0 AS FTE, convert(numeric(18,2),C.Salary/12) AS MonSalary, 0 AS MonFTE, ''1SAL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##salseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate FROM ##salseq AS C
UNION SELECT C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, ''1SAL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C UNION SELECT
C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, ''2SOC'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION SELECT C.Employee_ID, C.StartDate, C.Travel, NULL AS FTE, convert(numeric(18,2),C.Travel/12) AS MonSalary, NULL AS MonFTE, ''3TRA'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##traseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##traseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, C.Pension, NULL AS FTE, convert(numeric(18,2),C.Pension/12) AS MonSalary, NULL AS MonFTE, ''4PPL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##pplseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##pplseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, ''4PPL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, C.Other, NULL AS FTE, convert(numeric(18,2),C.Other/12) AS MonSalary, NULL AS MonFTE, ''5OTH'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##othseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##othseq AS C
) AS pt2 ON pt1.Employee_ID=pt2.Employee_ID AND pt1.ElementId=pt2.ElementId AND pt1.ValidFrom <= pt2.EndDate AND pt1.ValidTo >= pt2.StartDate
) AS pt4 ON pt3.Employee_ID=pt4.Employee_ID AND pt3.ElementId=pt4.ElementId AND pt3.SeriesID=pt4.SeriesID AND pt3.Year = ''' @year ''' AND pt3.Version = pt4.Version
AND pt3.MonthStart <= pt4.FteSalTo AND pt3.MonthEnd >= pt4.FteSalFrom
AND pt3.MonthStart <= pt4.SeriesValidTo AND pt3.MonthEnd >= pt4.SeriesValidFrom
) AS dat
GROUP BY dat.Employee_ID, dat.ElementId, dat.SeriesId, dat.Year, dat.Month, dat.Version, dat.Currency, dat.SeriesValidFrom, dat.SeriesValidTo
) AS sf
ON v.Employee_ID=sf.Employee_ID AND v.ElementId=sf.ElementId AND v.SeriesId=sf.SeriesId AND v.Year=sf.Year AND v.Version=sf.Version AND v.Month=sf.Month
'
print @sql1
Результат: Как мы можем видеть, она не принимает полную строку
UPDATE v
SET v.ValueLoc = (sf.ValueLoc*isnull(sf.FTE,1)*-1), v.FTE = sf.FTE, v.CurrencyLOC = sf.Currency, v.K4_MODIFIED = getDate()
FROM ##STAFF_PLAN_VALUES v
INNER JOIN (
SELECT
dat.Employee_ID, dat.ElementId, dat.SeriesId, dat.Year, dat.Month, dat.Version, dat.Currency, dat.SeriesValidFrom, dat.SeriesValidTo,
convert(numeric(18,2),sum(dat.MonSalRatio)) AS ValueLOC,
convert(numeric(18,2),sum(dat.MonFTE)) AS FTE
FROM (
SELECT
pt3.Employee_ID, pt3.SeriesId, pt3.ElementId, pt3.Year, pt3.Month, pt4.MonSalary, pt4.MonFTE, pt3.Version, pt4.Currency,
pt3.MonthStart, pt3.MonthEnd, pt4.SeriesValidFrom, pt4.SeriesValidTo, pt4.FteSalFrom, pt4.FteSalTo,
(CASE WHEN pt3.MonthStart>pt4.FteSalFrom THEN pt3.MonthStart ELSE pt4.FteSalFrom END) AS ValidFrom,
(CASE WHEN pt3.MonthEnd<pt4.FteSalTo THEN pt3.MonthEnd ELSE pt4.FteSalTo END) AS ValidTo,
cast((DATEDIFF(day,(CASE WHEN pt3.MonthStart>pt4.SeriesValidFrom THEN pt3.MonthStart ELSE pt4.SeriesValidFrom END),(CASE WHEN pt3.MonthEnd<pt4.SeriesValidTo THEN pt3.MonthEnd ELSE pt4.SeriesValidTo END)) 1) AS float)/
cast((DATEDIFF(day,pt3.MonthStart,pt3.MonthEnd) 1) AS float)*pt4.MonSalary AS MonSalRatio,
cast((DATEDIFF(day,(CASE WHEN pt3.MonthStart>pt4.SeriesValidFrom THEN pt3.MonthStart ELSE pt4.SeriesValidFrom END),(CASE WHEN pt3.MonthEnd<pt4.SeriesValidTo THEN pt3.MonthEnd ELSE pt4.SeriesValidTo END)) 1) AS float)/
cast((DATEDIFF(day,pt3.MonthStart,pt3.MonthEnd) 1) AS float)*pt4.MonFTE AS MonFTERatio
FROM (
SELECT v.*,
cast(cast(v.Year AS varchar(4)) '-' right('0' cast(v.Month AS varchar(2)),2) '-01' AS date) AS MonthStart,
dateadd(day,-1,dateadd(month,1,cast(cast(v.Year AS varchar(4)) '-' right('0' cast(v.Month AS varchar(2)),2) '-01' AS date))) AS MonthEnd
FROM ##STAFF_PLAN_VALUES AS v
) AS pt3 INNER JOIN (
SELECT
pt1.Employee_ID, pt1.SeriesID, pt1.ElementId,
pt1.ValidFrom AS SeriesValidFrom,
pt1.ValidTo AS SeriesValidTo,
pt2.StartDate AS FteSalFrom,
pt2.EndDate AS FteSalTo,
pt1.Version, pt1.PLCode, pt1.LegalEntityId,pt1.BusinessUnitId,pt1.DepartmentId,pt1.Currency,pt2.MonFTE,pt2.MonSalary
FROM
##STAFF_PLAN_ELEMENTS AS pt1
INNER JOIN (SELECT C.Employee_ID, C.StartDate, C.Salary, 0 AS FTE, convert(numeric(18,2),C.Salary/12) AS MonSalary, 0 AS MonFTE, '1SAL' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##salseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate FROM ##salseq AS C
UNION SELECT C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, '1SAL' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C UNION SELECT
C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, '2SOC' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION SELECT C.Employee_ID, C.StartDate, C.Travel, NULL AS FTE, convert(numeric(18,2),C.Travel/12) AS MonSalary, NULL AS MonFTE, '3TRA' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##traseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##traseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, C.Pension, NULL AS FTE, convert(numeric(18,2),C.Pension/12) AS MonSalary, NULL AS MonFTE, '4PPL' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##pplseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##pplseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS Mo
Любая помощь приветствуется.
Версия SQL Server: Microsoft SQL Server 2017 (RTM-CU18) (KB4527377) — 14.0.3257.3 (X64) Standard Edition (64-разрядная версия) на Windows Server 2016 Datacenter 10.0 (сборка 14393: ) (гипервизор)
Комментарии:
1. Вы подтверждаете, что строка не соответствует длине, которую я измеряю при выводе команды ПЕЧАТИ? Что такое
SELECT DATALENGTH(@sql1);
? Для некоторых других идей см. Проверка содержимого больших динамических строк SQL в SQL Server .2. Я не привык работать с Microsoft SQL, но, насколько я знаю, «длина» — это не количество символов, а размер в байтах. Некоторые символы занимают больше места, чем другие learn.microsoft.com/en-us/sql/t-sql/data-types /…
3. Не воспроизводимо . Я изменил
AND pt3.Year = ''' @year ''' AND
наAND pt3.Year = ' ''' @year''' ' AND
. Длина данных равна 58944. Также
@sql1
должно бытьnvarchar
, и если вам нужно более 4000 символов, вы должны использоватьmax
. Если вы правильно выполняете динамический SQL (например, передавая строго типизированные параметры, чтобы избежать внедрения SQL), вы бы использовалиsp_executesql
, что требуетnvarchar
. Смотрите это , это и это .5. @Inc
nvarchar(max)
длина составляет 2 ГБ. Если строка может быть длиннее 4000 символов, они должны использоватьnvarchar(max)
. Если у них есть строка SQL, которая превышает 2 ГБ, я думаю, что у них проблема посерьезнее, чем выбор типа данных.
Ответ №1:
Реальная проблема здесь не в типе данных, а в print()
команде в T-SQL, которая имеет ограничение в 4000 символов для NVARCHAR и 8000 символов для типов данных VARCHAR. Это восходит к какому-то старому SQL Server, когда NVARCHAR (MAX) был эквивалентен NVARCHAR (4000). Они изменили (МАКСИМАЛЬНОЕ) значение, но не print()
функцию.
Самое простое решение — не печатать его. Если вы попытаетесь вставить или выполнить код, он будет работать так, как ожидалось.
Для символов отсечения краткое руководство выглядит примерно так:
NVARCHAR (4000)
будет обрезана строка на 4000-м символе.VARCHAR (8000)
будет обрезана строка на 8000-м символе.NVARCHAR (MAX)
иVARCHAR (MAX)
просто достаточно велики для любой общей строки (~ 2 ГБ).
Вот воспроизводимый пример обоих значений ограничения и print()
проблемы:
DECLARE @SQL_varchar_8 VARCHAR (8000);
DECLARE @SQL_varchar_max VARCHAR (MAX);
DECLARE @SQL_nvarchar_8 NVARCHAR (4000);
DECLARE @SQL_nvarchar_max NVARCHAR (MAX);
declare @year int = 2020;
SET @SQL_varchar_8=
'
UPDATE v
SET v.ValueLoc = (sf.ValueLoc*isnull(sf.FTE,1)*-1), v.FTE = sf.FTE, v.CurrencyLOC = sf.Currency, v.K4_MODIFIED = getDate()
FROM ##STAFF_PLAN_VALUES v
INNER JOIN (
SELECT
dat.Employee_ID, dat.ElementId, dat.SeriesId, dat.Year, dat.Month, dat.Version, dat.Currency, dat.SeriesValidFrom, dat.SeriesValidTo,
convert(numeric(18,2),sum(dat.MonSalRatio)) AS ValueLOC,
convert(numeric(18,2),sum(dat.MonFTE)) AS FTE
FROM (
SELECT
pt3.Employee_ID, pt3.SeriesId, pt3.ElementId, pt3.Year, pt3.Month, pt4.MonSalary, pt4.MonFTE, pt3.Version`enter code here`, pt4.Currency,
pt3.MonthStart, pt3.MonthEnd, pt4.SeriesValidFrom, pt4.SeriesValidTo, pt4.FteSalFrom, pt4.FteSalTo,
(CASE WHEN pt3.MonthStart>pt4.FteSalFrom THEN pt3.MonthStart ELSE pt4.FteSalFrom END) AS ValidFrom,
(CASE WHEN pt3.MonthEnd<pt4.FteSalTo THEN pt3.MonthEnd ELSE pt4.FteSalTo END) AS ValidTo,
cast((DATEDIFF(day,(CASE WHEN pt3.MonthStart>pt4.SeriesValidFrom THEN pt3.MonthStart ELSE pt4.SeriesValidFrom END),(CASE WHEN pt3.MonthEnd<pt4.SeriesValidTo THEN pt3.MonthEnd ELSE pt4.SeriesValidTo END)) 1) AS float)/
cast((DATEDIFF(day,pt3.MonthStart,pt3.MonthEnd) 1) AS float)*pt4.MonSalary AS MonSalRatio,
cast((DATEDIFF(day,(CASE WHEN pt3.MonthStart>pt4.SeriesValidFrom THEN pt3.MonthStart ELSE pt4.SeriesValidFrom END),(CASE WHEN pt3.MonthEnd<pt4.SeriesValidTo THEN pt3.MonthEnd ELSE pt4.SeriesValidTo END)) 1) AS float)/
cast((DATEDIFF(day,pt3.MonthStart,pt3.MonthEnd) 1) AS float)*pt4.MonFTE AS MonFTERatio
FROM (
SELECT v.*,
cast(cast(v.Year AS varchar(4)) ''-'' right(''0'' cast(v.Month AS varchar(2)),2) ''-01'' AS date) AS MonthStart,
dateadd(day,-1,dateadd(month,1,cast(cast(v.Year AS varchar(4)) ''-'' right(''0'' cast(v.Month AS varchar(2)),2) ''-01'' AS date))) AS MonthEnd
FROM ##STAFF_PLAN_VALUES AS v
) AS pt3 INNER JOIN (
SELECT
pt1.Employee_ID, pt1.SeriesID, pt1.ElementId,
pt1.ValidFrom AS SeriesValidFrom,
pt1.ValidTo AS SeriesValidTo,
pt2.StartDate AS FteSalFrom,
pt2.EndDate AS FteSalTo,
pt1.Version, pt1.PLCode, pt1.LegalEntityId,pt1.BusinessUnitId,pt1.DepartmentId,pt1.Currency,pt2.MonFTE,pt2.MonSalary
FROM
##STAFF_PLAN_ELEMENTS AS pt1
INNER JOIN (SELECT C.Employee_ID, C.StartDate, C.Salary, 0 AS FTE, convert(numeric(18,2),C.Salary/12) AS MonSalary, 0 AS MonFTE, ''1SAL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##salseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate FROM ##salseq AS C
UNION SELECT C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, ''1SAL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C UNION SELECT
C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, ''2SOC'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION SELECT C.Employee_ID, C.StartDate, C.Travel, NULL AS FTE, convert(numeric(18,2),C.Travel/12) AS MonSalary, NULL AS MonFTE, ''3TRA'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##traseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##traseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, C.Pension, NULL AS FTE, convert(numeric(18,2),C.Pension/12) AS MonSalary, NULL AS MonFTE, ''4PPL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##pplseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##pplseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, 0 AS Salary, C.FTE, 0 AS MonSalary, convert(numeric(18,2),C.FTE) AS MonFTE, ''4PPL'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##fteseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION
SELECT
C.Employee_ID, C.StartDate, C.Other, NULL AS FTE, convert(numeric(18,2),C.Other/12) AS MonSalary, NULL AS MonFTE, ''5OTH'' AS ElementId,
isnull((SELECT max(dateadd(day,-1,D.StartDate)) FROM ##othseq AS D WHERE C.Employee_ID=D.Employee_ID AND C.SeqID=D.SeqID-1),C.FinalEndDate) AS EndDate
FROM ##othseq AS C
) AS pt2 ON pt1.Employee_ID=pt2.Employee_ID AND pt1.ElementId=pt2.ElementId AND pt1.ValidFrom <= pt2.EndDate AND pt1.ValidTo >= pt2.StartDate
) AS pt4 ON pt3.Employee_ID=pt4.Employee_ID AND pt3.ElementId=pt4.ElementId AND pt3.SeriesID=pt4.SeriesID AND pt3.Year = ''' cast(@year as varchar) ''' AND pt3.Version = pt4.Version
AND pt3.MonthStart <= pt4.FteSalTo AND pt3.MonthEnd >= pt4.FteSalFrom
AND pt3.MonthStart <= pt4.SeriesValidTo AND pt3.MonthEnd >= pt4.SeriesValidFrom
) AS dat
GROUP BY dat.Employee_ID, dat.ElementId, dat.SeriesId, dat.Year, dat.Month, dat.Version, dat.Currency, dat.SeriesValidFrom, dat.SeriesValidTo
) AS sf
ON v.Employee_ID=sf.Employee_ID AND v.ElementId=sf.ElementId AND v.SeriesId=sf.SeriesId AND v.Year=sf.Year AND v.Version=sf.Version AND v.Month=sf.Month
';
/*a bit of cheating to make it shorter*/
set @SQL_varchar_max = @SQL_varchar_8
set @SQL_nvarchar_8 = @SQL_varchar_8
set @SQL_nvarchar_max = @SQL_varchar_8
select len(@SQL_varchar_8) -- 5959
, len(@SQL_varchar_max) -- 5959
, len(@SQL_nvarchar_8) -- 3998
, len(@SQL_nvarchar_max); -- 5959
print(@SQL_nvarchar_max);
print('----------');
print(right(@SQL_nvarchar_max, 4000)); -- prints text that was cutoff in previous print()