SQL Server关闭ANSI_WARNING ON存储过程

Kob*_*kie 1 sql t-sql sql-server

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

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

但是,我希望关闭它,以便我期待这一点,而宁愿允许它.

我补充说

SET ANSI_WARNINGS OFF 
GO
Run Code Online (Sandbox Code Playgroud)

然而,在存储过程之前,执行此操作似乎根本不会抑制错误.

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

非常感谢如何最好地处理这个问题.提前致谢.

EBa*_*arr 5

我同意@marc_s - 修复问题,而不是症状,特别是如果你的意图是截断.当他出现并且proc抛出这些错误并使用非标准标志来解决问题时,另一位开发人员会怎么想?

代码使你的意图截断清楚.

识别问题
小提琴不会显示您描述的行为.所以我对这个问题仍然感到困惑.

此外,你的SQL小提琴太过密集,不适合这样的问题.如果我不回答你的问题,可以将问题分解为最简单的用例.不要只将500行应用程序转储到窗口中.

注意:Max NVarchar在SQL 7和2000版本中是4000或nvarchar(max)在SQL 2005及更高版本中是2 Gigs().我不知道你想出了什么3072.

我的测试

如果您在SPROC 参数级别截断,则会忽略ANSI警告标志,因为此MSDN页面会发出警告.如果它在你的程序中,我创建了一个小的测试proc,它显示允许截断的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);
Run Code Online (Sandbox Code Playgroud)

然后调用它以下按预期工作:

exec DoSomething 'Text string longer than 20 characters'
Run Code Online (Sandbox Code Playgroud)

解决问题

然而,为什么不只是编码所以你的意图(可能)截断数据是明确的?您可以避免警告而不是将其关闭.我会做以下其中一项:

  • 使您的过程参数足够长以容纳输入
  • 如果您需要缩短字符串数据用于Substring()修剪数据.
  • 根据您的要求使用CASTCONVERT格式化数据. 此页面(标题为 "隐式转化"应该有帮助)详细说明了转换和转换的工作原理.

我上面的简单示例可以修改如下,以避免设置任何标志.

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');
Run Code Online (Sandbox Code Playgroud)

一个Aside - Clustered Guids

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

希望您可以转换为int identity,您正在使用newsequentialid()或COMB guids,如 Jimmy Nilsson的文章中所述.您可以在此处,此处,此处此处查看有关此问题的更多信息.