問題描述:

客戶的asp系統有一功能,可編輯html內文,但程式送出後出現
Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80040e21'
[Microsoft][ODBC SQL Server Driver]字串資料,右側被截略

網頁是由asp程式執行DB Store Procedure進行資料的處理

原DB為MS SQL2000,但因應unicode及昇級至MS SQL2005(2008)
資料欄位改為nvarchar(max)

資料表及使用的預存程式如下:

CREATE TABLE [dbo].[TestContent](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[title] [nvarchar](400) NULL,
	[content] [nvarchar](max) NULL
) ON [PRIMARY]

CREATE PROCEDURE [dbo].[Insert_TestContent]
	@title		NVARCHAR(400),
	@content	NVARCHAR(MAX)
AS
	INSERT INTO TestContent(
		title,
		body
	)
	VALUES  (
		@title,
		@content
	)
GO

原程式碼:

Set objCommand = Server.CreateObject("ADODB.Command")
With objCommand
	Set .ActiveConnection = conn_t
	.CommandType = 4
	.CommandText = "Insert_TestContent"
	.Parameters.Refresh
	.Parameters.Item(1) = request("title")
	.Parameters.Item(2) = request("content")
	.Execute
End With		
Set objCommand = Nothing  

解決過程:

由錯誤訊息看來很清礎是字串被截(超過長度),同時進行以下測試

  1. 利用資料庫工具,直接對資料表寫入超過4000字元以上的資料,正常
  2. 利用資料庫工具,測試預存程式 Insert_TestContent,寫入超過4000字元以上的資料,正常
  3. 執行網頁,寫入長度4000字元,正常
  4. 執行網頁,寫入長度4001字元,出現錯誤訊息

經進一步查詢相關資料發現是asp程式使用ADODB.Command裡面的Parameter造成的問題
調整改寫後即可正常

調整後的程式碼:

Set objCommand = Server.CreateObject("ADODB.Command")
With objCommand
	Set .ActiveConnection = conn_t
	.CommandType = 4
	.CommandText = "Insert_TestContent"
	.prepared = true 
	.parameters.Append .CreateParameter("title",200,1,400,request("title")) 
	.parameters.Append .CreateParameter("content",203,1,-1,request("content"))
	.Execute
End With		
Set objCommand = Nothing	

補充: