Пропустить ПОСЛЕДНЮЮ строку с помощью OPENROWSET

Я делаю довольно прямой импорт файла .csv, предоставленного поставщиком, используя следующую команду (я немного сократил ее):

Вставить в... из OPENROWSET (Bulk 'CSVFileName', FORMATFILE = 'XMLFormatFileName', FIRSTROW = 2, MAXERRORS = 0) AS BulkLoadFile

Формат файла CSV выглядит следующим образом (вам может потребоваться щелкнуть, чтобы увидеть изображение, поскольку я новичок в StackOverflow и пока не могу напрямую публиковать изображения):

http://i.stack.imgur.com/qZMwV.jpg

Моя проблема - ПОСЛЕДНЯЯ СТРОКА со счетчиком... Это приводит к сбою импорта!

FYI >>> Да, я знаю, что вы можете использовать "SET NOCOUNT ON;" но я не генерирую этот файл, так что это не вариант.

Прямо сейчас я открываю файл и удаляю последнюю строку, а затем повторно сохраняю перед импортом. (примечание: я также удаляю верхние 2 строки, показанные зеленым цветом, поскольку я уже в файле, но две первые строки не являются проблемой, поскольку я могу пропустить эти строки, используя переключатель FIRSTROW = 4).

Итак, мои вопросы:

Есть ли способ ПРОПУСТИТЬ ПОСЛЕДНЮЮ РЯДКУ?

OR

Есть ли способ получить количество строк и, возможно, использовать переключатель LAST ROW? т.е. ПОСЛЕДНЯЯ СТРОКА = Счетчик(*) из myCSVfile

OR

Поскольку он всегда начинается как «Всего:», нужно ли в любом случае добавить предложение WHERE? то есть значение WHERE в первом столбце не похоже на «Всего:%»

OR

Это то, с чем SSIS справится лучше? Если это так, я могу перенести эту процедуру импорта в SSIS.

Заранее спасибо... Я с нетерпением жду возможности по-настоящему автоматизировать это и не открывать этот файл каждый раз, когда мы его импортируем (несколько раз в день).

D3Y


person D3Young    schedule 30.01.2015    source источник


Ответы (3)


Я вижу два варианта:

  1. вставьте данные во временную таблицу, очистите ненужные строки, а затем вставьте в финальную (производственную таблицу). Это можно сделать только с помощью T-SQL.

  2. используя пакет SSIS (в частности, задачу потока данных), вы можете использовать условное разделение, чтобы отфильтровать ненужные строки. например https://www.simple-talk.com/sql/ssis/ssis-basics-using-the-conditional-split/

person ivankristof    schedule 30.01.2015
comment
спасибо за отзыв, но эти решения не решают мою проблему... Я не могу импортировать файл (во временную или производственную таблицу) из-за последней строки. - person D3Young; 30.01.2015
comment
вы получили какую-либо ошибку? на основании того, что вы предоставили, я не вижу никаких препятствий для того, чтобы последняя строка не могла быть импортирована, а затем удалена (не перемещена) в конечную/производственную таблицу. - person ivankristof; 31.01.2015
comment
ivankristof, вы правы... Это было больше о том, что я неправильно использовал переключатель MAXERRORS. Спасибо за ответ! - person D3Young; 03.02.2015

РЕШЕНИЕ найдено...

Я использовал MAXERRORS = 0

Если я предполагаю (да, я знаю шутку о предположении), что у меня будет 1 (ожидаемая) ошибка, связанная с последней строкой, я могу использовать MAXERRORS = 1, и мои данные импортируются нормально. Последняя строка (всего: xxxx) импортируется в мою таблицу, но я могу просто игнорировать эту строку, когда использую ее дальше в конвейере обновлений.

Также стоит отметить... Если max_errors не указан, значение по умолчанию равно 10 , поэтому я мог бы избежать этого, даже не используя переключатель MAXERRORS... Поди разберись.

Справочная информация: MSDN (msdn.microsoft.com/en-us/library/ms188365.aspx) Указывает максимальное количество синтаксических ошибок, допустимых в данных, до отмены операции массового импорта. Каждая строка, которую невозможно импортировать с помощью операции массового импорта, игнорируется и считается одной ошибкой.

person D3Young    schedule 30.01.2015

Я только что сделал команду openrowset, которая предшествует той, для которой мне нужно знать последнюю строку, и направила ее на рассматриваемый файл. Установите в файле форматирования только разделитель (один столбец), установите терминатор строки (в данном случае \n). Это был мой очень простой файл формата:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\n" MAX_LENGTH="10000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Column0" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

Затем я использовал этот счет минус 1 в дальнейшем.

DECLARE @File VARCHAR(200);

SET @File = '''Dir\path\';
SET @File += 'filename.txt''';

DECLARE @SQL4Rows NVARCHAR(max)

SET @SQL4Rows = (
        'select count (*) FROM OPENROWSET(BULK 
        ' + @file + 
        ', 
        FORMATFILE = 
        ''\\fullformatfilepath_rowCountOnly.xml'') T'
        )

DECLARE @SQL4RowsTable AS TABLE (col INT)

INSERT INTO @SQL4RowsTable
EXECUTE sp_executesql @SQL4Rows

DECLARE @Rows VARCHAR(6)

SET @Rows = (
        SELECT *
        FROM @SQL4RowsTable
        ) - 1 --the last line of the files is the row count, thus the minus 1

DECLARE @SQL4Results NVARCHAR(max) --main sql to get results

SET @SQL4Results = (
        '
SELECT column,etc,
INTO #inlinetemp
FROM OPENROWSET(BULK ' + @File + 
        ', 
        FORMATFILE = 
        ''\\fullformatfilepath.xml'',LASTROW = ' + @Rows + 
        ') T
WHERE column = ''la''
SELECT DISTINCT columns
FROM #inlinetemp ab
LEFT JOIN db..tblaccounts a
    ON ab.accountnumber = a.AccountNumber
ORDER BY column asc '
        )

EXECUTE sp_executesql @SQL4Results
person Dropbear    schedule 18.05.2017