如何使用ExecuteNonQuery在VARCHAR(MAX)列中插入超过8000个字符?

时间:2013-01-15 23:22:31

标签: c# sql-server-2008 enterprise-library executenonquery varcharmax

我正在尝试插入> 8000个字符(通过网页提交)通过ExecuteNonQuery(以及来自MS Practices Enterprise Library的DatabaseFactory.CreateDatabase())。存储过程将参数定义为VARCHAR(MAX)。该列为VARCHAR(MAX)。理论上,应该能够传递2GB的数据。

如何传递数据> 8000?我设置了一个断点,string.Length确实是> 8K。

   public static void UpdateTerms(string terms)
   {
        Database db = DatabaseFactory.CreateDatabase();
        db.ExecuteNonQuery("uspUpdateTerms", terms);
    }

存储过程:

ALTER PROCEDURE [dbo].[uspUpdateTerms]
    @Terms VARCHAR(MAX)
AS
  SET NOCOUNT ON

  INSERT INTO tblTerms(Terms)
  VALUES(@Terms)

表(只是为了表明所有内容都是varchar(max)):

CREATE TABLE [dbo].[tblTerms](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Terms] [varchar](max) NULL,
[DateUpdated] [datetime] NULL,

更新

我刚刚更改了代码,这似乎有效,但我不确定区别是什么:

 public static void UpdateTerms(string terms)
 {
        Database db = DatabaseFactory.CreateDatabase();
        DbCommand cmd = db.GetStoredProcCommand("uspUpdateTerms");
        db.AddInParameter(cmd, "Terms", DbType.String, terms);
        db.ExecuteNonQuery(cmd);
 }

4 个答案:

答案 0 :(得分:3)

无论以后的分配如何,

REPLICATE都会返回输入类型。这很烦人,但要避免静默截断,请尝试:

SET @x = REPLICATE(CONVERT(VARCHAR(MAX), 'a'), 10000);

这是因为SQL Server在考虑您要分配的内容或尝试将其扩展到的字符数之前执行REPLICATE操作。它只关心输入表达式以确定它应该返回什么,如果输入不是max类型,它假定它适合8,000字节。这在Books Online

中有解释
  

如果string_expression的类型不是varchar(max)或nvarchar(max),则REPLICATE会将返回值截断为8,000字节。要返回大于8,000字节的值,必须将string_expression显式转换为适当的大值数据类型。

答案 1 :(得分:2)

您可以通过执行以下操作修复示例代码:

declare @x varchar(max)
set @x = replicate (cast('a' as varchar(max)), 10000)
select @x, len(@x)

答案 2 :(得分:2)

问题可能不是数据的存储,可能是检索。

如果您正在尝试通过企业管理器确定是否在数据库中存储了超过8000个字符,那么如果您只选择列的内容并查看文本长度,那么您就不走运了:企业管理器限制列输出。

要确定列中实际存储的数据量,请执行以下查询:

SELECT DATALENGTH(Terms) FROM tblTerms

这将告诉您存储了多少文本。

编辑:

刚刚发生了另一个想法:企业库缓存存储过程参数以提高性能。如果在测试后使用参数设置为nvarchar(8000)更改了存储过程,则将参数切换为nvarchar(max)而不重置应用程序(如果是IIS托管,则iisreset或脏{{1然后你仍然会使用旧的存储过程参数。

答案 3 :(得分:1)

您尚未显示尝试使用ExecutenonQuery的代码。请注意,您应该使用参数。

using(var con = new SqlConnection(conString))
using(var cmd = new SqlCommand("storedProcedureName", con))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@text", SqlDbType.NVarChar, -1);
    cmd.Parameters["@text"].Value = yourVeryLongText;
    cmd.ExecuteNonQuery();
}