我们使用标准System.Data
类DbConnection
和DbCommand
从C#连接到SQL Server,我们有许多存储过程可以使用VARCHAR
或{{ 1}}参数作为输入。我们发现,当长度超过参数最大长度的字符串作为该参数的值传入时,SQL Server和C#应用程序都不会抛出任何类型的错误或警告。而是将该值静默截断为参数的最大长度。
因此,例如,如果存储过程输入的类型为NVARCHAR
并且我们传入VARCHAR(10)
,则存储过程接收输入为'U R PRETTY STUPID'
,这非常好但完全不是我们想说的。
我过去做过什么来检测这些截断,以及others have likewise suggested是什么使参数输入长度大于所需的一个字符,然后检查输入的长度是否等于新的最大长度。所以在上面的示例中,我的输入将变为'U R PRETTY'
,我将检查长度为11的输入。任何长度为11或更长的输入都将被此检查捕获。这有效,但感觉不对。理想情况下,数据访问层会自动检测这些问题。
有没有更好的方法来检测提供的存储过程输入是否超过允许的时间? VARCHAR(11)
不应该已经知道输入长度限制了吗?
另外,作为一个好奇心,是什么导致默默地截断我们的输入?
答案 0 :(得分:3)
对所有变量和参数使用VARCHAR(8000)
,NVARCHAR(4000)
甚至N/VARCHAR(MAX)
。这样,在分配@variables和@parameters时,您无需担心截断。截断可能在实际数据写入(插入或更新)时发生,但这不是静默,会触发硬错误,你会发现它。您还可以获得存储过程代码的额外好处,而不必通过架构更改进行更改(更改列长度,代码仍然有效)。您还可以使用一致的参数长度获得更好的计划缓存行为,请参阅How Data Access Code Affects Database Performance。
请注意,对于@ variables / @参数使用MAX类型会有轻微的性能影响,请参阅Performance comparison of varchar(max) vs. varchar(N)。