如何防止我的存储过程输入被静默地截断
本文关键字:静默 输入 何防止 我的 存储过程 | 更新日期: 2023-09-27 18:21:07
我们使用标准的System.Data
类DbConnection
和DbCommand
从C#连接到SQL Server,并且我们有许多以VARCHAR
或NVARCHAR
参数为输入的存储过程。我们发现,当一个超过参数最大长度的字符串作为该参数的值传入时,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)的性能比较。