我同意@marc_s - 解决问题,而不是症状,特别是如果您的意图是 truncate。当另一个开发人员出现并且 proc 抛出这些错误并且使用非标准标志来抑制问题时,他会怎么想?
使您的截断意图清晰的代码。
确定您的问题
小提琴没有显示您描述的行为。所以我对这个问题仍然有些困惑。
此外,对于这样的问题,您的 SQL 小提琴太密集了。如果我没有在下面回答您的问题,请尽可能将问题隔离到最简单的用例中。不要只是将 500 行应用程序转储到一个窗口中。
注意:Max NVarchar 在 SQL 7 和 2000 版本中为 4000,nvarchar(max)
在 SQL 2005 及更高版本中为 2 Gigs ( )。我不知道你从哪里想出 3072。
我的测试
如果您在 SPROC参数级别截断,则忽略 ANSI 警告标志,因为此 MSDN 页面警告。如果它在您的过程中,我创建了一个小测试过程,显示允许截断的 ANSI 标志:
CREATE Proc DoSomething (@longThing varchar(50)) AS
DECLARE @T1 TABLE ( shortThing VARCHAR(20) );
SET ANSI_WARNINGS OFF
Print ' I don''t even whimpler when truncating'
INSERT INTO @T1 (ShortThing) VALUES ( @longThing);
SET ANSI_WARNINGS ON
Print ' I yell when truncated'
INSERT INTO @T1 (ShortThing) VALUES ( @longThing);
然后调用它按预期工作:
exec DoSomething 'Text string longer than 20 characters'
解决问题
尽管如此,为什么不直接编写代码,以便(可能)截断数据的意图很明确?您可以避免警告而不是将其关闭。我会执行以下操作之一:
- 使您的过程参数足够长以容纳输入
- 如果您需要缩短
Substring()
用于修剪数据的字符串数据。
- 使用
CAST
或CONVERT
将数据格式化为您的要求。 此页面(标题为“隐式转换”的部分应该有所帮助)详细介绍了 cast & convert 的工作方式。
我上面的简单示例可以修改如下,以避免需要设置任何标志。
CREATE Proc DoSomethingBETTER (@longThing varchar(50)) AS
SET ANSI_WARNINGS ON
DECLARE @T1 TABLE ( shortThing VARCHAR(20) );
--try one of these 3 options...
INSERT INTO @T1 (ShortThing) VALUES ( Convert(varchar(20), @longThing));
INSERT INTO @T1 (ShortThing) VALUES ( Substring(@longThing, 1, 20));
INSERT INTO @T1 (ShortThing) VALUES ( Cast(@longThing as varchar(20)) );
Print('Ansi warnings can be on when truncating data');
旁白——集群向导
看着你的小提琴,我注意到你Uniqueidentifer
是聚集索引中的关键。在几乎所有情况下,这都是一个非常低效的选择。GUID 的随机性意味着您的数据不断被碎片化和重新洗牌。
希望您可以转换为Jimmy Nilsson 的文章int identity
中所述的、正在使用newsequentialid()
的或 COMB 指南 。您可以在此处、此处、此处和此处查看有关该问题的更多信息。