2

ExecuteNonQuery我正在尝试通过(以及DatabaseFactory.CreateDatabase()来自 MS Practices Enterprise Library)插入 > 8000 个字符(从网页提交)。存储过程将参数定义为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

4 回答 4

3

REPLICATE返回输入类型,而不考虑以后的分配。这很烦人,但为了避免静默截断,请尝试:

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

这是因为 SQL Server 在REPLICATE考虑您将其分配给什么或您尝试将其扩展为多少字符之前执行该操作。它只关心输入表达式来确定它应该返回什么,如果输入不是最大类型,它假定它应该适合 8,000 字节。这在联机丛书中进行了解释:

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

于 2013-01-15T22:41:53.277 回答
2

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

declare @x varchar(max)
set @x = replicate (cast('a' as varchar(max)), 10000)
select @x, len(@x)
于 2013-01-15T22:41:59.103 回答
2

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

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

要确定该列中实际存储了多少数据,请执行以下查询:

SELECT DATALENGTH(Terms) FROM tblTerms

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

编辑:

另一个想法刚刚出现:企业库缓存存储过程参数以提高性能。如果您在将参数设置为 测试后更改了存储过程nvarchar(8000),然后在不重置应用程序的情况下将参数切换为nvarchar(max)(如果 IIS 托管,则为iisresetweb.config),那么您仍将使用旧的存储过程参数。

于 2013-01-15T23:32:48.813 回答
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();
}
于 2013-01-15T22:45:36.303 回答