根据这个论坛的讨论,SQL Server(我使用的是2005,但我收集到的信息也适用于2000和2008)varchar
,即使您直接使用INSERT
实际上会导致错误。例如。如果我创建此表:
CREATE TABLE testTable(
[testStringField] [nvarchar](5) NOT NULL
)
然后当我执行以下命令时:
INSERT INTO testTable(testStringField) VALUES(N'string which is too long')
我收到一个错误:
String or binary data would be truncated.
The statement has been terminated.
大。数据完整性得以保留,并且调用者知道这一点。现在让我们定义一个存储过程来插入它:
CREATE PROCEDURE spTestTableInsert
@testStringField [nvarchar](5)
AS
INSERT INTO testTable(testStringField) VALUES(@testStringField)
GO
并执行它:
EXEC spTestTableInsert @testStringField = N'string which is too long'
没有错误,影响了1行。在表中插入一行,并testStringField
以'strin'开头。SQL Server默默地截断了存储过程的varchar
参数。
现在,这种行为有时可能很方便,但我认为没有办法将其关闭。这非常令人讨厌,因为如果我将太长的字符串传递给存储过程,我希望事情出错。似乎有两种方法可以解决此问题。
首先,将存储的proc的@testStringField
参数声明为大小6,并检查其长度是否超过5。这似乎有点不合时宜,并且涉及到令人讨厌的样板代码。
其次,只需将所有存储过程的varchar参数声明为varchar(max)
,然后让INSERT
存储过程中的语句失败。
后者似乎工作正常,所以我的问题是:varchar(max)
如果我真的希望在传递字符串的时间过长时存储过程失败,那么对SQL Server存储过程中的字符串始终使用ALWAYS是个好主意吗?可能是最佳做法吗?在我看来,无法禁用的无声截断是愚蠢的。