курсор сервера sql

Я хочу скопировать данные из одной таблицы (rawdata, все столбцы – VARCHAR) в другую таблицу (отформатированную в соответствующем формате столбца).

Для копирования данных из таблицы rawdata в formatted таблицу я использую курсор, чтобы определить, какая строка затронута. Мне нужно записать эту конкретную строку в таблицу журнала ошибок, пропустить ее и продолжить копирование оставшихся строк.

Для копирования требуется больше времени. Есть ли другой способ достичь этого? это мой запрос

 DECLARE @EntityId Varchar(16) , @PerfId Varchar(16), @BaseId Varchar(16) , @UpdateStatus Varchar(16) DECLARE CursorSample CURSOR FOR SELECT EntityId, PerfId, BaseId, @UpdateStatus FROM RawdataTable --Returns 204,000 rows OPEN CursorSample FETCH NEXT FROM CursorSample INTO @EntityId,@PerfId,@BaseId,@UpdateStatus WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY --try insertting row in formatted table Insert into FormattedTable (EntityId,PerfId,BaseId,UpdateStatus) Values (Convert(int,@EntityId), Convert(int,@PerfId), Convert(int,@BaseId), Convert(int,@UpdateStatus)) END TRY BEGIN CATCH --capture Error EntityId in errorlog table Insert into ERROR_LOG (TableError_Message,Error_Procedure,Error_Log_Time) Values (Error_Message()[email protected],'xxx', GETDATE()) END CATCH FETCH NEXT FROM outerCursor INTO @EntityId, @BaseId END CLOSE CursorSample DEALLOCATE CursorSampler –cleanup CursorSample 

Вы должны просто использовать инструкцию INSERT INTO, чтобы помещать записи непосредственно в форматированную таблицу. INSERT INTO будет работать намного лучше, чем с помощью курсора.

 INSERT INTO FormattedTable SELECT CONVERT(int, EntityId), CONVERT(int, PerfId), CONVERT(int, BaseId), CONVERT(int, UpdateStatus) FROM RawdataTable WHERE IsNumeric(EntityId) = 1 AND IsNumeric(PerfId) = 1 AND IsNumeric(BaseId) = 1 AND IsNumeric(UpdateStatus) = 1 

Обратите внимание, что IsNumeric иногда может возвращать 1 для значений , которые затем будут сбой в CONVERT . Например, IsNumeric('$e0') вернет 1, поэтому вам может понадобиться создать более надежную пользовательскую функцию для определения, является ли строка числом, в зависимости от ваших данных.

Кроме того, если вам нужен журнал всех записей, которые нельзя переместить в форматированную таблицу, просто измените предложение WHERE:

 INSERT INTO ErrorLog SELECT EntityId, PerfId, BaseId, UpdateStatus FROM RawdataTable WHERE NOT (IsNumeric(EntityId) = 1 AND IsNumeric(PerfId) = 1 AND IsNumeric(BaseId) = 1 AND IsNumeric(UpdateStatus) = 1) 

РЕДАКТИРОВАТЬ
Вместо использования IsNumeric напрямую может быть лучше создать пользовательский UDF, который скажет вам, может ли строка быть преобразована в int. Эта функция работала для меня (хотя и с ограниченным тестированием):

 CREATE FUNCTION IsInt(@value VARCHAR(50)) RETURNS bit AS BEGIN DECLARE @number AS INT DECLARE @numeric AS NUMERIC(18,2) SET @number = 0 IF IsNumeric(@value) = 1 BEGIN SET @numeric = CONVERT(NUMERIC(18,2), @value) IF @numeric BETWEEN -2147483648 AND 2147483647 SET @number = CONVERT(INT, @numeric) END RETURN @number END GO 

Обновленный SQL для вставки в форматированную таблицу будет выглядеть следующим образом:

 INSERT INTO FormattedTable SELECT CONVERT(int, CONVERT(NUMERIC(18,2), EntityId)), CONVERT(int, CONVERT(NUMERIC(18,2), PerfId)), CONVERT(int, CONVERT(NUMERIC(18,2), BaseId)), CONVERT(int, CONVERT(NUMERIC(18,2), UpdateStatus)) FROM RawdataTable WHERE dbo.IsInt(EntityId) = 1 AND dbo.IsInt(PerfId) = 1 AND dbo.IsInt(BaseId) = 1 AND dbo.IsInt(UpdateStatus) = 1 

Может возникнуть небольшая странность при обработке NULL (моя функция вернет 0, если NULL передан, хотя INT может быть нулевым), но это можно настроить в зависимости от того, что должно произойти с значениями NULL в RawdataTable .

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

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

Вставка в работу будет намного лучше, чем Cursor. Поскольку курсор работает исключительно в памяти вашего ПК и замедляет оптимизацию SQL Server. Нам следует избегать использования курсоров, но (конечно) бывают ситуации, когда использование курсора невозможно избежать.

  • Как узнать последнюю строку при повторении курсора на SQL Server?
  • Курсор внутри курсора
  • Курсор SQL Server - цикл через несколько серверов и выполнение запроса
  • XML-файл SQL Server с несколькими узлами с одинаковым именем
  • Передача c # DataTable в качестве параметра хранимой процедуры в MS SQL Server 2008
  • Получение нескольких значений в курсоре SQL Server
  • Использование курсора API базы данных с JDBC и SQLServer для выбора пакетных результатов
  • Удалить оператор SQL cursur
  • Выбрать из списка таблиц в SQL Server
  • Как выбрать информацию из строки выше?
  • Может ли этот курсор быть оптимизирован или переписан для оптимальной производительности?
  • Interesting Posts

    Подсчет количества успешных побитовых совпадений

    Несколько записей в sys.partition для несегментированной таблицы

    Устранение дубликатов в отношениях от 1 до многих в SQL Server

    Преобразование приложения на основе EF в многопользовательский режим с помощью контекстных переопределений

    Как сохранить таблицу, синхронизированную с запросом в SQL Server – ETL?

    Вложенные выбирает в соединениях: идентификатор с несколькими частями не может быть связан

    Как умножить одну строку с числом из столбца в sql

    GUID против Int

    Как использовать двойную переменную в SQL-заявлении на C #?

    Фильтровать динамически xml дочерний элемент с xslt с помощью SSIS

    Справка по SQL-запросу с таблицей моста

    SQL – копирование определенных строк в таблицу в одну и ту же таблицу и изменение их значений

    Сохранить результат хранимой процедуры в переменной таблицы

    Как удалить несколько хранимых процедур в одной базе данных

    Используя случай для присвоения числовых значений и достижения наивысшего значения

    Давайте будем гением компьютера.