Как автоматически обрезать строку при массовой вставке?

Я хочу вставить много строк (составленных из объектов Entity Framework) в SQL Server. Проблема в том, что длина некоторых строковых свойств превышает длину столбца в базе данных, что вызывает исключение, после чего все строки не могут быть вставлены в базу данных.

Поэтому мне интересно, есть ли способ заставить SqlBulkCopy автоматически усекать любые слишком длинные строки? Конечно, я могу проверить и подстроку каждого свойства, если оно превышает ограниченную длину, прежде чем вставлять его в DataTable, но это замедлит работу всей программы.


person Quan Mai    schedule 19.06.2011    source источник


Ответы (3)


Всегда используйте промежуточную/загрузочную таблицу для массовых действий.

Затем вы можете обрабатывать, очищать, очищать и т. д. данные перед сбросом в реальную таблицу. Это включает в себя LEFT, поиск, дедупликацию и т. д.

So:

  1. Загрузите промежуточную таблицу с широкими столбцами.
  2. Сбросить из промежуточной таблицы в «настоящую» с помощью INSERT realtable (..) SELECT LEFT(..), .. FROM Staging
person gbn    schedule 19.06.2011

К сожалению, нет прямого способа сделать это с помощью SqlBulkCopy. Массовые вставки SQL по своей природе почти «тупые», но именно поэтому они такие быстрые. Они даже не регистрируются (кроме захвата события SqlRowsCopied), поэтому, если что-то не получается, информации мало. То, что вы ищете, будет в некотором роде противоречить цели этого класса.

Но может быть 2 возможных пути:

  • Вы можете попробовать использовать SqlBulkCopyOptionsEnumeration (передается в конструктор SqlBulkCopy()) и использовать SqlBulkCopyOptions.CheckConstraints ( Проверяйте ограничения во время вставки данных. По умолчанию ограничения не проверяются.).

  • Или вы можете использовать перечисление SqlBulkCopyOptions.FireTriggers (если указано, заставить сервер запускать триггеры вставки для строк, вставляемых в базу данных.) и обрабатывать исключение в SQL Server Insert Trigger.

person Shekhar_Pro    schedule 19.06.2011
comment
-1 Триггер сработает слишком поздно: усечение происходит до запуска кода. Проверка по-прежнему тоже дает исключение. Оп вернулся к тому, с чего начал. - person gbn; 19.06.2011
comment
+0,5? С помощью триггера INSTEAD OF INSERT вы можете обрезать данные для вставки, но лучше использовать промежуточную таблицу. - person SqlACID; 19.06.2011

Попробуйте использовать класс SQLTransaction при использовании класса SQLBulkCopy

person Rahul    schedule 22.07.2015