我需要知道如何关闭存储过程中的ANSI警告。我一直收到错误
字符串或二进制数据将被截断。
但是,我希望关闭它,因为我期待这一点,而宁愿允许它。
我添加了声明
SET ANSI_WARNINGS OFF
GO
然后在存储过程之前,这样做似乎根本不能抑制错误。
由于我开始使用此截断错误的原因,我的一个存储过程执行动态Sql以检索值(SQLFIddle showing the code)。我必须将所有字段的长度设置为最大长度(NVarchar(3072))。然而,当执行我的查询时,我需要将它们打印到正确的大小,然后将它们打印到客户端。
请欣赏有关如何最好地处理此问题的信息。提前致谢。
答案 0 :(得分:5)
我同意@marc_s - 解决问题,而不是症状,特别是如果您的意图是截断。当他出现并且proc抛出这些错误并使用非标准标志来解决问题时,另一位开发人员会怎么想?
使你的意图截断清楚的代码。
识别您的问题
小提琴不会显示您描述的行为。所以我对这个问题仍然感到困惑。
此外,对于像这样的问题,你的SQL小提琴方式过于密集。如果我不回答你的问题,可以将问题分解为最简单的用例。不要只将500行应用程序转储到窗口中。
注意:Max NVarchar在SQL 7和版本的版本中是4000。 SQL 2005及更高版本中的2000或2 Gigs(nvarchar(max)
)。我不知道你在哪里提出3072。
我的测试
如果您在SPROC 参数级别截断,则会忽略ANSI警告标志,因为this MSDN page会发出警告。如果它在你的程序中,我创建了一个小的测试过程,显示允许截断的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
将数据格式化为您的要求。 This page(标题为“隐含转化”应该有所帮助)详细说明了演员与演员的关系。转换工作。上面的简单示例可以修改如下,以避免需要设置任何标志。
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的随机性意味着您的数据不断被分割。重新洗牌。
希望您可以转换为int identity
,使用newsequentialid()
或COMB guid,如Jimmy Nilsson's article中所述。
您可以详细了解问题here,here,here和here。