调试存储过程

时间:2015-07-26 13:36:42

标签: sql sql-server sql-server-2005

我致力于支持基于SQL Server 2005的大型复杂项目。它包含800多个存储过程和1000个表。大多数存储过程包含2000多行,有些还有10000多行代码。每个表包含200多列。

大多数存储过程包含while循环,游标,而另一个游标循环中的循环非常复杂。我们使用许多临时表,表变量超过200列

发生任何错误时我都会遇到困难。最常见的错误如下:

  

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

  

将数字转换为数据类型varchar

的算术溢出错误

等等

找出哪个列发生错误非常困难。由于上述错误消息只显示错误而不是实际列。

由于有超过200列,找出罪魁祸首已成为一项艰巨的任务。我必须对几列进行注释/硬编码,并且需要检查错误是否正在发生。

请在下面找一个示例,以便更好地了解我的问题:

DECLARE @tablevar TABLE( Column1 int, column2 char(2),column char(6),.....
......,**Column137 char(7)**,..............column199 char(7), column(200) char(6))

......some code...

--while loop

while i < count  

Begin

--some code

Insert into @tablevar(Column1, column2,column3,.....
.....,**column137**...............column199, column200))

select t1.OthertableColumn1,t1.OthertableColumn2,t2.OthertableColumn3,t3.Othertablecolumn4,...
....,**t2.OthertableColumn137**,....

so on..........

t2.Column200)

from OtherTable t1 with (nolock)

LEFT JOIN OtherTable2 t2 with (nolock) on t1.col1 = t2.Column1

LEFT JOIN OtherTable3 t3 with (nolock) on t3.col1 = t2.Column1

LEFT JOIN OtherTable4 t4 with (nolock) on t4.col1 = t3.Column1

LEFT JOIN OtherTable5 t5 with (nolock) on t5.col1 = t1.Column1

LEFT JOIN OtherTable6 t6 with (nolock) on t6.col2 = t4.Column1

....
End

列Column137发生实际错误。表变量@tablevar的列column137的大小是7个字符,但是它插入了更多的字符,例如, &#39;样本数据&#39;。因此抛出错误 - 字符串或二进制数据将被截断。

如何从200个大量的列中识别出这个Column137?有没有办法找到发生错误的特定列名?

有没有找到确切列的快捷方式/简单方法?

我们将不胜感激。

1 个答案:

答案 0 :(得分:0)

你不会喜欢这个答案。它涉及工作,可能不适合生产(您可能只需启用它来进行故障排除)。

您没有指明数据的来源,但我们假设SQL参数,以及一个很好的名称,如@pForColumn137

这两个选项都是作为示例提供的,只对正在讨论的当前列有所帮助 - 完整的解决方案需要每列的类似代码(是的,yuck)

选项1:将插入更改为SUBSTRING(@pForColumn137,1,7)

...但这只是避免错误并默默地截断

选项2:添加

IF @LEN(@pForColumn137) > 7 RAISERROR ('Column 137 value is too long!',16,1);

...但是这会引发一个至少更具体的硬错误。可以获得更好的消息 - 使用本地@MSG VARCHAR变量并构建消息以传递到RAISERROR

要测试Arithmetic overflow error converting numeric to data type varchar,你需要编写类似下面的内容......这里假装@ForColumn137是INT ...它的可能等级为10,并不总是适合VARCHAR(7)

IF @LEN(LTRIM(STR(@pForColumn137))) > 7 RAISERROR('Value for Column 137 requires too many characters')

或者如果你喜欢花哨的数学并且真的在处理整数

IF CEILING(LOG10(@pForColumn137) ) > 7 RAISERROR('Value for Column 137 requires too many characters')

警告:如果包含十进制值,这些数字到字符串测试都会变得更复杂。如果您知道有效的小数,STR会使用两个可选参数。 LOG10技巧不适用

祝你好运。