如何解决声明为Varchar8000的SQL变量在5160处修剪内容
我已声明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,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.MonthEnd)+1) AS float)*pt4.MonSalary AS MonSalRatio,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,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,C.Salary/12) AS MonSalary,0 AS MonFTE,''1SAL'' AS ElementId,isnull((SELECT max(dateadd(day,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,0 AS Salary,C.FTE,0 AS MonSalary,C.FTE) AS MonFTE,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,''2SOC'' AS ElementId,C.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION SELECT C.Employee_ID,C.Travel,NULL AS FTE,C.Travel/12) AS MonSalary,NULL AS MonFTE,''3TRA'' AS ElementId,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.Pension,C.Pension/12) AS MonSalary,''4PPL'' AS ElementId,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.FinalEndDate) AS EndDate
FROM ##fteseq AS C
UNION
SELECT
C.Employee_ID,C.Other,C.Other/12) AS MonSalary,''5OTH'' AS ElementId,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.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,pt3.Version,cast(cast(v.Year AS varchar(4)) + '-' + right('0' + cast(v.Month AS varchar(2)),2) + '-01' AS date) AS MonthStart,2) + '-01' AS date))) AS MonthEnd
FROM ##STAFF_PLAN_VALUES AS v
) AS pt3 INNER JOIN (
SELECT
pt1.Employee_ID,'1SAL' AS ElementId,'2SOC' AS ElementId,'3TRA' AS ElementId,'4PPL' AS ElementId,C.FTE) AS Mo
感谢您的帮助。
sql Server版本: Microsoft sql Server 2017(RTM-CU18)(KB4527377)-14.0.3257.3(X64) Windows Server 2016 Datacenter 10.0(内部版本14393:)(管理程序)上的标准版(64位)
解决方法
真正的问题不是数据类型,是T-SQL中的Object
命令,它对NVARCHAR的限制为4000个字符,对VARCHAR数据类型的限制为8000个字符。当NVARCHAR(MAX)与NVARCHAR(4000)等效时,这可以回溯到一些旧的SQL Server。他们更改了(MAX)含义,但没有更改print()
函数。
最简单的解决方案是避免打印它。如果您尝试插入或执行代码,它将按预期工作。
对于截止字符,快速指南类似于:
-
print()
将从第4000个字符处截断该字符串。 -
NVARCHAR (4000)
将从第8000个字符处截断该字符串。 -
VARCHAR (8000)
和NVARCHAR (MAX)
足够大,可以容纳任何通用字符串(〜2GB)。
以下是临界值和VARCHAR (MAX)
问题的可重现示例:
print()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。