2015-04-28 2 views
3

Я запускаю приложение .NET 4.0, которое обменивается данными с использованием LINQ to SQL с SQL Server 2008 R2 Standard Edition. У меня есть таблица со столбцом типа nvarchar(max), и приложение заполняет этот столбец строками как часть его работы.Длинные строки, усеченные при вводе времени

Для строк размером> ~ 30 МБ мы обнаруживаем, что после завершения вставки \ обновления часть строки усекается, а то, что хранится на сервере, не является полной строкой. Дело в том, что строки усекаются в переменных положениях (мы по-прежнему оставляем более 30 МБ данных после усечения), поэтому нет какой-либо фиксированной точки, которая может привести меня в сторону ограничения размера (хотя это все еще может это так).

Я не вижу ошибок во время ввода, хотя иногда я замечаю, что при таких длинных вставках \ обновления сервер SQL закрывает соединение. Но разве операция не должна откатываться в этом случае?

Поблагодарили бы за идеи. Не уверен, как действовать дальше.

+0

Возможно, вам необходимо сохранить это как текст, а не nvarchar (max). В зависимости от того, какие другие данные у вас есть в этой строке, вы можете столкнуться с общей шириной строки. Взгляните на https://technet.microsoft.com/en-us/library/ms186981%28v=sql.105%29.aspx – LordBaconPants

+4

@LordBaconPants типы данных text и ntext устарели и не будут использоваться для новых реализаций. MS четко заявляет, что вы shoud используете varchar (max) и nvarchar (max) – Blim

+0

Зачем вам хранить 30 МБ строковых данных в одном столбце db?Похоже, у вас проблема моделирования здесь в базе данных. Кроме того, мне кажется, что ваша проблема с усечением все еще может быть в вашем приложении. Если вы используете веб-службы, вероятно, есть ограничение на отправку и получение, например, например, в случае службы WCF: http://stackoverflow.com/questions/884235/wcf-how-to-increase-message -size-quota – maplemale

ответ

3

Я подозреваю, что это не 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(); 
} 

Когда это завершается успешно (то есть запрос завершается до истечения таймаута); следующий запрос показывает, что все 30 000 000 символов были переданы и вставлены; когда он терпит неудачу с таймаутом, таблица пуста.

select len(Data) from LongStringTruncation; 

Обратите внимание, что я использовал SQL 2014 здесь, так что это может быть есть ошибка в SQL 2008 R2, которые могли бы раскрыть этот тест. Мой тест также использует параметры, и если вы вместо этого используете конкатенацию строк для создания своего SQL, это может быть еще одним источником проблем.

Если ни один из них не объясняет проблему, то единственный вывод, который имеет смысл, заключается в том, что само приложение каким-то образом обрезает данные, прежде чем вставлять их. Учитывая случайный характер, я бы подумал, что мои первые подозреваемые будут воспринимать то, как вы получите строковые данные (например, буферизованный поток без покраски перед чтением результата), или какой-то многопоточный ранг при получении значения/сигнализации, что он будет завершен.

0

У меня была такая же проблема. Решено путем изменения типа данных входных параметров в хранимой процедуре.

Повторите следующие действия: Тип данных входного параметра хранимой процедуры должен быть таким же, как тип данных столбца таблицы, в который вы вставляете значение.

Также проверьте то же самое в коде C#.

Тип данных и его длина Для примера: VARCHAR(50) должно быть одинаковым для SP, таблицы и кода.

Смежные вопросы