根据本次论坛讨论,SQL Server(我使用的是 2005,但我收集这也适用于 2000 和 2008)默默地截断任何varchar
您将 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
作为“字符串”。 SQL Server 默默地截断了存储过程varchar
范围。
现在,这种行为有时可能很方便,但我认为没有办法将其关闭。这非常烦人,因为我want如果我向存储过程传递太长的字符串,就会出错。似乎有两种方法可以解决这个问题。
首先,声明存储过程@testStringField
参数大小为 6,并检查其长度是否超过 5。这看起来有点像 hack,并且涉及大量令人恼火的样板代码。
其次,只需将所有存储过程 varchar 参数声明为varchar(max)
,然后让INSERT
存储过程中的语句失败。
后者似乎工作正常,所以我的问题是:使用是一个好主意吗varchar(max)
对于 SQL Server 存储过程中的字符串总是如此,如果我真的希望存储过程在传递太长的字符串时失败?这可能是最佳实践吗?无法禁用的静默截断对我来说似乎很愚蠢。