我正在处理将生成html页面的查询。最初,该页面只是带有标签的简单HTML表。标签稍后将被处理并替换为子查询(主要是标量函数)。这种将带有替换标记的HTML组合在一起的方法将与sp_executesql一起执行以生成最终的html。
该HTML的摘录:
...Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Firma:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Companyname,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Anrede:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Anrede,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Vorname:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Firstname,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold;">Nachname:</td><td style="font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif;">'+(select cast(coalesce(Lastname,'') as nvarchar(max)) as result from Customer WHERE CustomerID=988082)+'</td></tr><tr><td style="font-size: 1...
现在,我知道如果我使用除nvarchar(max)以外的任何内容,我的结果将被截断为4000,因此我将所有函数结果都转换为nvarchar(max),而我的结果不止于此,但仍然奇怪地削减了从内部。
因此,当我运行示例脚本时,得到的结果是 9043 个字符(带有len函数),并且结果被切除(注意:从内部开始,在结尾附近,但不在结尾处) )。现在,我附加一个字母,结果为 9044 。但是,如果我在最终结果之前添加字母100个字符,仍然是 9043 !!?
这有什么问题?为什么我不能建立一个长的T-SQL查询以执行预期的结果?
谢谢
更新1
因为原始解决方案太长了,无法在此处显示,所以我将尝试显示较小的版本,以供您了解我的工作方式以及最终的解决方法:
declare @BodyTXT nvarchar(max)
set @BodyTXT = N'select ''some string' + (select cast('result of some function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another AAA string' + (select cast('result of antoher function' as nvarchar(max))) + N''''
execute sp_executesql @BodyTXT
让我们说这是LEN = 9043个字符,现在,注意AAA,如果我在此处添加字符,最终结果将保持为LEN = 9043,但是如果我在开始时添加一些字符串,则字符串大小将改变并增加我在其中添加的字符串数。
结果将以这种方式截取:
some stringresult of some function another stringresult of antoher function
another stringresult of antoher function another stringresult of antoher
function another stringresult of antoher function another stringresult of antoher
function another stringresult of antoher function another ...ult of antoher function
您能在结果的末尾看到那些...点吗?那是我缺少应该在输出中显示的其余字符串的地方(大约12000,我有9043)
更新2
因为这都是自动化电子邮件系统的一部分,并且正在运行中,所以我不得不找到解决方案,而我要做的就是从结果表中删除一些样式信息。因此,在剪切了html的1/3之后,我最终获得了预期的结果,但是最终字符串的大小取决于客户购买了多少产品,因此肯定会再次出现此问题。而且我也想知道这种行为的原因是什么,以及如何克服它。
答案 0 :(得分:1)
我知道这是一个旧帖子,但仍然是当前主题。 这只是一个仅供参考,以帮助在此主题上需要帮助的任何人。
我刚遇到一个问题,我的@SqlStr(设置为 NVARCHAR(MAX))在 SP_ExecuteSQL 调用期间不断切断导致错误。
对这个长脚本进行的唯一连接是@TableName,它被设置为 NVARCHAR(100)。
经过几个小时的调试,问题是由@tablename 引起的
似乎当使用 nvarchar(###) 而不是 NVarchar(max) 时,SQL 将其视为一种略有不同的数据类型并将长字符串切割为 4000 个字符。
为了解决这个问题,我必须更改@Tablename 以匹配 nvarchar(max) 数据类型。
答案 1 :(得分:0)
在生成大型html输出作为字符串时,我想起了类似的内容。不记得是什么问题了,可能是Management Studio的某些限制。解决方法是将表生成为xml。以下是您可以尝试的示例。首先生成sql表,然后用表替换“ select * from(values ..)”。
declare
@baseTable xml = (select * from ( Values
(123, 'Firma:', 'Google'),
(123, 'Anrede:', 'NYC'),
(123, 'Vorname:', 'John'),
(123, 'Nachname:', 'Doe')
) T(CustID, property, Val)
for XML PATH('row'), ELEMENTS XSINIL)
,@tblClass VARCHAR(100)
,@thClass VARCHAR(100)
,@TRstyle VARCHAR(100) = 'font-size: 14px'
,@TDstyle VARCHAR(100) = 'font-size: 14px; font-family: Arial, Helvetica, Verdana, sans-serif; font-weight: bold'
SELECT @tblClass AS [@class]
,@thClass AS [thead/@class]
,@baseTable.query(
N'let $first:=/row[1]
return
<tr>
{
for $th in $first/*
return <th>{local-name($th)}</th>
}
</tr>') AS thead
,@baseTable.query(
N'for $tr in /row
return
<tr style="{sql:variable("@TRstyle")}">
{
for $td in $tr/*
return <td style="{sql:variable("@TDstyle")}">{string($td)}</td>
}
</tr>') AS tbody
FOR XML PATH('table'),TYPE
答案 2 :(得分:0)
我曾经遇到一个使用+ =运算符来连接长字符串的问题,这使字符减少了。
因此,使用@SQL = @SQL + N'a really long text';
可以解决此问题。
答案 3 :(得分:0)
问题几乎可以肯定是,您的@BodyTXT可能是nvarchar(max),但您输入的不是。通过设置@BodyTxt = a + b + c + d + .....,首先完成所有串联,然后立即将其插入变量中。很好,直到某个地方由于类型强制(或其他原因)SQL决定最新位的结果是nvarchar(默认长度4000),而不是nvarchar(max),然后将其中的一部分截断。
您可以遍历整个查询,检查所有内容并查找问题,但将串联分解为足够小的对象可能会更简单,诸如此类。
declare @BodyTXT nvarchar(max)
set @BodyTXT = N'select ''some string' + (select cast('result of some function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max)))
set @BodyTXT = @BodyTXT +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
set @BodyTXT = @BodyTXT +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another string' + (select cast('result of antoher function' as nvarchar(max))) +
N' another AAA string' + (select cast('result of antoher function' as nvarchar(max))) + N''''
答案 4 :(得分:-1)
LEN
会修剪尾随空格,DATALENGTH
不会修剪。 select len('a '), datalength('a ')
。因此,如果您向后插入该字母100个字符,则最后一个字符为空格。只需使用DATALENGTH
即可,您应该得到预期的结果。