我有一个Foo
包含以下字段的表:
ID bigint not null identity(1,1),
SerializedValue nvarchar(max),
LongValue as TRY_CAST(SerializedValue as bigint)
现在我想在 LongValue 上创建一个索引,以便我可以轻松地查找代表数字的序列化值。
create nonclustered index IX_Foo on Foo(LongValue);
这向我吐出以下错误:
字符串或二进制数据将被截断。
是的,SerializedValue 中有现有数据。但是,祈祷,可以通过在计算字段上创建索引来截断什么?
该错误不是由创建索引引起的。该错误是由
TRY_CAST
在创建索引时评估计算列值引起的。如果我运行这个:
我犯了同样的错误。
文档说(强调我的):
现在,尚不清楚在哪种情况下它会失败并出现错误(考虑到函数的全部要点,这似乎有点愚蠢,但无论如何......),所以我们可以通过转换输入值来修复代码(使用一些东西对表中的数据是合理的),因为当它不适合 bigint 时,无需处理巨大的字符串:
这将返回
NULL
,因为该值无效,但它不会因错误而爆炸。如果字符串的值太长,则索引创建将失败。我使用 SQL Server 2012 尝试了一些测试代码。
我的快速实验表明,只要 nvarchar(max) 值为 4000 个字符或更少,代码就可以工作。(当然,最后没有任何内容的所有空白都折叠为没有字符,因此工作正常。)第 4001 个字符触发
String or binary data would be truncated
消息。因此,您可能会检查您的数据中是否有超过 4000 个字符的 SerializedValue。编辑:是的,转换为
BIGINT
. 问题不在于BIGINT
,而在于NVARCHAR(MAX)
。例如:CREATE INDEX
将值转换为BIGINT
.CREATE INDEX
,但值可能是NULL
因为它溢出BIGINT
。CREATE INDEX
失败。因此,NVARCHAR(MAX) 的实际内容似乎对 CREATE INDEX 很重要。
编辑:Jon Seigel 发现当字符串长于 nvarchar(4000) 时,TRY_CAST 会触发创建索引失败。