如何防止我的存储过程输入被静默地截断

本文关键字:静默 输入 何防止 我的 存储过程 | 更新日期: 2023-09-27 18:21:07

我们使用标准的System.DataDbConnectionDbCommand从C#连接到SQL Server,并且我们有许多以VARCHARNVARCHAR参数为输入的存储过程。我们发现,当一个超过参数最大长度的字符串作为该参数的值传入时,SQL Server和C#应用程序都不会抛出任何类型的错误或警告。相反,该值被静默地截断为参数的最大长度。

因此,例如,如果存储过程输入的类型是VARCHAR(10),并且我们传入'U R PRETTY STUPID',则存储过程接收的输入为'U R PRETTY',这非常好,但完全不是我们想要说的。

我过去所做的检测这些截断的工作,以及其他人同样建议的,是使参数输入长度比所需长度大一个字符,然后检查输入的长度是否等于新的最大长度。所以在上面的例子中,我的输入将变成VARCHAR(11),并且我将检查长度为11的输入。任何长度为11或以上的输入都将被此检查捕获。这是有效的,但感觉不对。理想情况下,数据访问层将自动检测这些问题。

是否有更好的方法来检测所提供的存储过程输入比允许的更长?DbCommand难道不应该已经知道输入长度限制吗?

此外,出于好奇,是什么在默默地截断我们的输入?

如何防止我的存储过程输入被静默地截断

对所有变量和参数使用VARCHAR(8000)NVARCHAR(4000)甚至N/VARCHAR(MAX)。这样,在分配@variables和@parameters时就不必担心截断了。截断可能会在实际数据写入(插入或更新)时发生,但这并不是静默的,会触发一个硬错误,您会发现它。您还可以获得存储过程代码的额外好处,即不必随架构更改而更改(更改列长度,代码仍然有效)。您还可以通过使用一致的参数长度获得更好的计划缓存行为,请参阅数据访问代码如何影响数据库性能。

请注意,对@variables/@参数使用MAX类型会对性能造成轻微影响,请参阅varchar(MAX)与varchar(N)的性能比较。