#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. Извините, просто обновил ссылку на другой сайт с тем же типом руководства.