Используйте SQL OpenRowSet BulkColumn для вставки данных из файла .txt

#sql-server #tsql

#sql-сервер #tsql

Вопрос:

Я хочу выполнить команду OpenRowSet, чтобы извлечь содержимое файла .txt в 1 столбец. В моем скрипте мне нужно перебирать коллекцию существующих записей и создавать динамический путь к файлу для каждого файла .txt, который я хочу импортировать в базу данных, и поэтому я использую процедуру sp_executesql для выполнения команды OpenRowSet и вывода содержимого файла .txt в выходной параметр.

Я протестировал OpenRowSet с жестко заданным путем к файлу и без передачи его в процедуру sp_executesql, и я могу получить содержимое файла .txt и вставить его в нужную мне таблицу в SQL. Все это работает. Проблема, с которой я сталкиваюсь с процедурой sp_executesql, заключается в том, что выходной параметр возвращается пустым. Вот фрагмент кода, который я запускаю в MSSQL SMS версии 15.0.18206.0 на Windows Server 2019.

 DECLARE     @rootDirectory          VARCHAR(100)
DECLARE     @filePathWithName       VARCHAR(255)
DECLARE     @txtFileContents        VARCHAR(MAX)
DECLARE     @commandText            NVARCHAR(MAX)

Set @commandText = N'(Select BulkColumn FROM OPENROWSET (BULK '''  @rootDirectory   @filePathWithName   ''', SINGLE_CLOB) Myfile)'

-- Print the command text, should contain full text file path.
print 'Command Text: '   @commandText

-- Execute command and output text file contents.
EXEC sp_executesql @commandText, 
                   N'@fileContentsOut VARCHAR(MAX) OUTPUT', 
                   @fileContentsOut = @txtFileContents OUTPUT;

-- Select the file contents output.
SELECT @txtFileContents;  -- <-- comes back empty???
  

Когда я выполняю приведенную выше команду, я получаю окно результатов запроса, в котором отображается содержимое файла .txt в столбце с именем «BulkColumn», но параметр @txtFileContents пуст.

Вот как выглядит @CommandText перед выполнением:

 Command Text: (Select BulkColumn FROM OPENROWSET (BULK 'F:Assetsmypathmyfile12345.TXT', SINGLE_CLOB) Myfile)
  

Я не понимаю, почему @txtfileContents возвращается пустым, когда я его выбираю.

Ответ №1:

Попробуйте это вместо:

 DECLARE @txtFileContents VARCHAR(MAX);

SELECT @txtFileContents = BulkColumn
FROM OPENROWSET ( BULK 'F:Assetsmypathmyfile12345.TXT', SINGLE_CLOB ) AS x;

SELECT @txtFileContents AS TxtFileContents;
  

Обновить:

Я перебираю список записей и каждый раз создаю динамический путь к файлу…

Это работает для меня:

 DECLARE 
    @cmd nvarchar(1000),
    @file nvarchar(255) = 'F:Assetsmypathmyfile12345.TXT',
    @txtFileContents varchar(MAX);

SET @cmd = FORMATMESSAGE ( 'SELECT @txtFileContents = BulkColumn FROM OPENROWSET ( BULK ''%s'', SINGLE_CLOB ) AS x;', @file );
EXEC sp_executesql @cmd, N'@txtFileContents varchar(MAX) OUT', @txtFileContents = @txtFileContents OUT;

SELECT @txtFileContents AS TxtFileContents;
  

Оказывается, вам не хватает SELECT @fileContentsOut = BulkColumn в вашем @commandText .

Это:

 SET @commandText = N'SELECT BulkColumn FROM OPENROWSET (BULK '''  @rootDirectory   @filePathWithName   ''', SINGLE_CLOB) Myfile;'
  

Необходимо:

 SET @commandText = N'SELECT @fileContentsOut = BulkColumn FROM OPENROWSET (BULK '''  @rootDirectory   @filePathWithName   ''', SINGLE_CLOB) Myfile;'
  

Комментарии:

1. Критическая ошибка, это то, что я делал для успешного использования жестко запрограммированного пути к файлу, но, как я уже упоминал, я перебираю список записей и каждый раз создаю динамический путь к файлу, и этот метод не принимает параметр для пути к файлу. Вот почему я использую процедуру sp_executesql .

2. Ну, это облом. Я буду копать дальше.

3. Да, это должно быть что-то простое, что я делаю неправильно. Просто не могу понять, почему выходной параметр возвращается пустым.

4. @GJGerson ознакомьтесь с обновлением моего ответа. Это работает для меня.

5. @GJGerson Для записи, вы были правы. Это была простая проблема, lol.

Ответ №2:

Можно использовать SSIS с контейнером for для каждого цикла.

https://www.red-gate.com/simple-talk/sql/ssis/ssis-basics-introducing-the-foreach-loop-container/

Комментарии:

1. Эта ссылка была помечена WebRoot, и вредоносная программа bytes заразила!!!!!!! НЕ НАЖИМАЙТЕ!!!!!!!!

2. Извините, просто обновил ссылку на другой сайт с тем же типом руководства.