Команда BCP выполняет каждую строку SQL-команды в таблице

#sql-server #tsql #bcp

#sql-сервер #tsql #bcp

Вопрос:

Я написал процедуру, которая экспортирует все данные SQL-запроса в файл csv с заголовком. Но я не знаю ошибку, показанную как показано ниже.

Сообщение 512, уровень 16, состояние 1, строка 26 Подзапрос вернул более 1 значения. Это не разрешено, когда подзапрос следует =, !=, <, <= , >, >= или когда подзапрос используется как выражение. Сообщение 512, уровень 16, состояние 1, строка 27 Подзапрос вернул более 1 значения. Это не разрешено, когда подзапрос следует =, !=, <, <= , >, >= или когда подзапрос используется как выражение.

Здесь с моим образцом базы данных

введите описание изображения здесь

Здесь с моим кодом

 DECLARE @SQLCmd varchar(max)
    DECLARE @FilePathCmd varchar(max)
    DECLARE @ExportCmd varchar(max)

    SET @SQLCmd=(SELECT CommandText from TestDB.dbo.CommandExportData)
    SET @FilePathCmd=(SELECT FilePath from TestDB.dbo.CommandExportData)

    

   SELECT @ExportCmd='bcp "' @SQLCmd '" queryout "' @FilePathCmd '" -c -t, -T -S'   @@servername
   print(@ExportCmd)
   exec master..xp_cmdshell @ExportCmd
 

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

1. Не видя кода, на самом деле недостаточно информации, чтобы помочь с вопросом. Тем не менее, ошибка кажется вполне понятной.

2. @GordonLinoff готово с кодом

3. Что сбивает с толку? CommandExportData содержит более одной строки.

4. Поскольку SQL может считывать только первую строку данных, невозможно продолжить выполнение второй строки данных

5. Это один из очень немногих случаев, когда вам понадобится курсор, если этот подход следует считать хорошим подходом для начала. Лично я бы настоятельно предпочел вместо этого написать клиентский код для этого; это может быть так же просто, как сценарий PowerShell, запланированный с помощью планировщика задач.

Ответ №1:

Здесь с помощью оператора Cursor, который я создал для выполнения каждой команды SQL строки в таблице

 use TestDB

DECLARE @storedprocedure_name varchar(100)
DECLARE @cmd VARCHAR(4000)

DECLARE @FilePath varchar(100)
DECLARE @FileNames varchar(100)

DECLARE spCursor CURSOR FAST_FORWARD FOR 
SELECT CommandText,FilePath,FileNames FROM dbo.MultipleQuery
OPEN spCursor
FETCH NEXT FROM spCursor INTO @storedprocedure_name ,@FilePath,@FileNames
WHILE @@fetch_status = 0
BEGIN

 SET @cmd = 'bcp "'  
  @storedprocedure_name   '" queryout "'   @FilePath  @FileNames  '" -c -UTF8 -T -S' @@SERVERNAME
PRINT @cmd


EXEC master..xp_cmdshell @cmd

 FETCH NEXT FROM spCursor INTO @storedprocedure_name,@FilePath,@FileNames
END
CLOSE spCursor
DEALLOCATE spCursor