2012-01-23 65 views
5

我們使用標準的System.Data類,DbConnectionDbCommand,從C#連接到SQL Server,並且我們有許多存儲過程,其中參數爲VARCHARNVARCHAR作爲輸入。我們發現,當超過參數最大長度的字符串作爲該參數的值傳入時,SQL Server和C#應用程序都不會引發任何類型的錯誤或警告。而是將該值默認截斷爲參數的最大長度。如何讓我的存儲過程輸入無提示被截斷?

因此,舉例來說,如果存儲過程的輸入是VARCHAR(10)型的,我們通過在'U R PRETTY STUPID',存儲過程接收輸入爲'U R PRETTY',這是非常好的,但絕對不是我們的意思是說。

我在過去所做的檢測這些截斷以及什麼others have likewise suggested,是使參數輸入長度比所需的一個字符大,然後檢查輸入的長度是否等於新的最大長度。所以在上面的例子中,我的輸入將變成VARCHAR(11),並且我將檢查長度爲11的輸入。長度爲11或更長的任何輸入將被該檢查捕獲。這有效,但感覺不對。理想情況下,數據訪問層會自動檢測這些問題。

有沒有更好的方法來檢測提供的存儲過程輸入是否比允許的更長? DbCommand是否已經知道輸入長度限制?

另外,出於好奇,什麼是負責靜靜地截斷我們的投入?

+0

你可以擺脫字符限制,而使用CHECK約束嗎? –

+0

@MikeChristensen - 你可以擴展一下你的意思嗎?我們的表格已經被正確的數據類型(和長度),FK和'CHECK'限制所約束。我所關心的是在我們使用任何存儲過程邏輯或查詢之前檢測超限輸入。 –

+0

哦,我很抱歉,我以爲你是直接插入表格。你正在談論sproc參數。你能把它變成一個'VARCHAR(MAX)',然後檢查sproc的長度嗎? –

回答

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)