长字符串在插入时被截断。
长字符串在插入时被截断。
我正在运行一个使用 LINQ to SQL 与 SQL Server 2008 R2 Standard 版本通信的 .NET 4.0 应用程序。我有一个带有 nvarchar(max) 类型列的表,应用程序会填充该列以完成其操作。
对于大于约30 MB的字符串,我们发现一旦插入\\更新完成,一部分字符串会被截断,存储在服务器中的不是完整的字符串。问题是字符串在可变位置被截断(截断后仍然有超过 30 MB 的数据),因此没有一些固定的点可引导我朝着某个大小限制的方向前进(尽管这仍然可能是情况)。
在插入时我没有看到任何错误,尽管有时我会注意到在这样的长插入\\更新期间 SQL Server 会关闭连接 - 但在这种情况下操作不应该被回滚吗?
希望有一些思路。不确定该如何继续。
admin 更改状态以发布 2023年5月23日
我怀疑不是SQL Server或连接插入数据的问题。我想知道是在设置命令参数值或甚至在应用程序内部时数据损坏了。我已经尝试使用连接和命令超时来插入时引发它们,以及您的假设取消隐式事务将回滚是正确的。以下是一个示例:
// Use connection with timeout of 1 second to generate a timeout when inserting using (var conn = new SqlConnection(@"Data Source=(localdb)\mssqllocaldb;Integrated Security=SSPI;Initial Catalog=tempdb;Connection Timeout=1")) using (var cmd = conn.CreateCommand()) { cmd.CommandTimeout = 1; conn.Open(); cmd.CommandText = @"if not exists(select * from sys.tables where name = 'LongStringTruncation') begin create table LongStringTruncation (Data nvarchar(max)); end"; cmd.ExecuteNonQuery(); cmd.CommandText = "insert LongStringTruncation values (@t)"; var t = cmd.CreateParameter(); t.DbType = DbType.String; t.ParameterName = "@t"; t.Value = new String('A', 30000000); // 30,000,000 chars = 60MB cmd.Parameters.Add(t); cmd.ExecuteNonQuery(); }
当这成功时(即在超时之前完成查询),以下查询显示已传输并插入了所有3000万个字符;当超时失败时,表格是空的。
select len(Data) from LongStringTruncation;
请注意,我在此处使用的是SQL 2014,因此可能存在SQL 2008 R2中的错误,此测试可以发现。我的测试还使用了参数,如果您使用字符串连接来构建SQL,这可能是另一个问题的来源。
如果这两个都无法解释问题,那么唯一有意义的结论是应用程序本身在插入之前以某种方式截断了数据。考虑到随机性,我会首先考虑获取字符串数据的方式(例如,读取结果之前没有刷新的缓冲流),或在获取值/发出完成信号时出现了一些多线程竞争。