SQL Server关闭ANSI_WARNING ON存储过程

时间:2012-10-13 15:18:46

标签: sql sql-server tsql

我需要知道如何关闭存储过程中的ANSI警告。我一直收到错误

  

字符串或二进制数据将被截断。

但是,我希望关闭它,因为我期待这一点,而宁愿允许它。

我添加了声明

SET ANSI_WARNINGS OFF 
GO

然后在存储过程之前,这样做似乎根本不能抑制错误。

由于我开始使用此截断错误的原因,我的一个存储过程执行动态Sql以检索值(SQLFIddle showing the code)。我必须将所有字段的长度设置为最大长度(NVarchar(3072))。然而,当执行我的查询时,我需要将它们打印到正确的大小,然后将它们打印到客户端。

请欣赏有关如何最好地处理此问题的信息。提前致谢。

1 个答案:

答案 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()修剪数据。
  • 使用CASTCONVERT将数据格式化为您的要求。 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');

Aside - Clustered Guids

看着你的小提琴,我注意到你Uniqueidentifer是你的聚集索引中的关键。在几乎每种情况下,这都是一个非常低效的选择。 GUID的随机性意味着您的数据不断被分割。重新洗牌。

希望您可以转换为int identity,使用newsequentialid()或COMB guid,如Jimmy Nilsson's article中所述。 您可以详细了解问题herehereherehere