C# 如何使用ExecuteOnQuery在VARCHAR(MAX)列中插入8000多个字符?
我正试图通过C# 如何使用ExecuteOnQuery在VARCHAR(MAX)列中插入8000多个字符?,c#,sql-server-2008,enterprise-library,executenonquery,varcharmax,C#,Sql Server 2008,Enterprise Library,Executenonquery,Varcharmax,我正试图通过ExecuteNonQuery(以及MS Practices Enterprise Library中的DatabaseFactory.CreateDatabase())插入>8000个字符(从网页提交)。存储过程将参数定义为VARCHAR(MAX)。该列为VARCHAR(MAX)。理论上,2GB的数据应该能够被传递 我可以做什么来传递大于8000的数据?我设置了一个断点,string.Length确实>8K public static void UpdateTerms(stri
ExecuteNonQuery
(以及MS Practices Enterprise Library中的DatabaseFactory.CreateDatabase()
)插入>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)
):
更新:
我刚刚更改了代码,这似乎有效,但我不确定区别是什么:
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);
}
REPLICATE
返回输入类型,与以后的赋值无关。这很烦人,但要避免无声截断,请尝试:
SET @x = REPLICATE(CONVERT(VARCHAR(MAX), 'a'), 10000);
这是因为SQL Server在考虑将其分配给什么或尝试将其扩展到多少个字符之前,会执行复制
操作。它只关心输入表达式,以确定它应该返回什么,如果输入不是max类型,则它假定它应该适合8000字节。下文对此进行了解释:
如果字符串_表达式不是varchar(max)或nvarchar(max)类型,则REPLICATE会将返回值截断为8000字节。若要返回大于8000字节的值,必须将字符串_表达式显式转换为相应的大值数据类型
您的示例代码可以通过以下操作修复:
declare @x varchar(max)
set @x = replicate (cast('a' as varchar(max)), 10000)
select @x, len(@x)
您尚未显示尝试使用
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();
}
问题可能不是数据的存储,而是检索 如果您试图通过enterprise manager确定数据库中存储的字符是否超过8000个,那么如果您只选择列的内容并查看文本长度:enterprise manager限制列的输出,那么您就是运气不佳 要确定列中实际存储了多少数据,请执行以下查询:
SELECT DATALENGTH(Terms) FROM tblTerms
这将告诉您存储了多少文本
编辑:
另一个想法刚刚出现:企业库缓存存储过程参数以提高性能。如果在测试后将参数设置为
nvarchar(8000)
,然后在不重置应用程序的情况下将参数切换为nvarchar(max)
(如果IIS托管,则iisreset
或dirtyweb.config
),则仍将使用旧的存储过程参数。,如果我这样做了:插入测试(数据)值(@x+@x+@x)选择数据,Len(数据)从测试。。。它显示24000(不是30K),但显然允许>8K@twoleggedhorse-a
被视为varchar(1)
而不是nvarchar(8000)
(甚至没有这样的数据类型)我的意思是说varchar不是nvarchar,我已经重新发布了我的评论,因为我无法编辑它again@twoleggedhorse-是什么?超过8000个字符的字符串文字被视为varchar(max)
。正如现有答案已经指出的那样,它是使用复制。将varchar(1-8000)
连接到varchar(1-8000)
将导致截断。我以前没有注意到这种行为,但是默认情况下,“a”(未声明的字符串类型)被视为varchar(8000),您必须将其强制转换为varchar(MAX)+对于这个问题,我理解这个测试,但最终我该如何完成我要做的事情,即使用ExecuteOnQuery通过C#程序>8K?@Investor5555我不知道从C#发送更大的查询有任何问题(如果你的查询文本长度大于8K,也许你应该考虑存储过程、参数化查询、表值参数等)。也许你的问题应该说明这个问题而不是我们回答的问题?这完全是SQL问题——未定义的字符串类型被视为NVARCHAR(8000)。默认情况下,@twoleggedhorse没有NVARCHAR(8000)
。公共静态void UpdateTerms(字符串术语){Database db=DatabaseFactory.CreateDatabase();db.ExecuteNonQuery(“usupdateterms”,terms);}@twoleggedhorse…那不是NVARCHAR(4000)吗
?@Investor5555请不要在评论中塞进一堆代码。读起来有趣吗?要么更新你的问题以反映你的实际问题,要么开始一个新问题,因为已经有解决你最初描述的[非常不同]问题的答案。可能就是这样。SP是VARCHAR(8000)我改变了它。我把我的代码恢复到原来的样子,它也可以工作。它一定是被缓存了。你搞定了!太棒了。
SELECT DATALENGTH(Terms) FROM tblTerms