экспортировать таблицу в файл с заголовками столбцов (именами столбцов) с помощью утилиты bcp и SQL Server 2008.

StackOverflow https://stackoverflow.com/questions/1355876

  •  20-09-2019
  •  | 
  •  

Вопрос

Я видел несколько попыток заставить утилиту bcp экспортировать имена столбцов вместе с данными.Если все, что я делаю, это выгружаю таблицу в текстовый файл, какой самый простой способ заставить bcp добавить заголовки столбцов?

Вот команда bcp, которую я сейчас использую:

bcp myschema.dbo.myTableout myTable.csv /SmyServer01 /c /t, -T
Это было полезно?

Решение

Самый простой – использовать queryout вариант и использовать union all чтобы связать список столбцов с фактическим содержимым таблицы

    bcp "select 'col1', 'col2',... union all select * from myschema.dbo.myTableout" queryout myTable.csv /SmyServer01 /c /t, -T

Пример:

create table Question1355876 
(id int, name varchar(10), someinfo numeric)

insert into Question1355876 
values (1, 'a', 123.12)
     , (2, 'b', 456.78)
     , (3, 'c', 901.12)
     , (4, 'd', 353.76)

Этот запрос вернет информацию с заголовками в первой строке.(Обратите внимание на приведение числовых значений)

select 'col1', 'col2', 'col3'
union all
select cast(id as varchar(10)), name, cast(someinfo as varchar(28))
from Question1355876

Команда bcp будет:

bcp "select 'col1', 'col2', 'col3' union all select cast(id as varchar(10)), name, cast(someinfo as varchar(28)) from Question1355876" queryout myTable.csv /SmyServer01 /c /t, -T

Другие советы

Этот метод автоматически выводит имена столбцов с данными вашей строки, используя ППГ.

Скрипт записывает один файл для заголовков столбцов (читается из INFORMATION_SCHEMA.COLUMNS table), затем добавляет еще один файл с данными таблицы.

Конечный результат объединяется в TableData.csv который имеет заголовки и данные строк.Просто замените переменные среды вверху, чтобы указать имя сервера, базы данных и таблицы.

set BCP_EXPORT_SERVER=put_my_server_name_here
set BCP_EXPORT_DB=put_my_db_name_here
set BCP_EXPORT_TABLE=put_my_table_name_here

BCP "DECLARE @colnames VARCHAR(max);SELECT @colnames = COALESCE(@colnames + ',', '') + column_name from %BCP_EXPORT_DB%.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='%BCP_EXPORT_TABLE%'; select @colnames;" queryout HeadersOnly.csv -c -T -S%BCP_EXPORT_SERVER%

BCP %BCP_EXPORT_DB%.dbo.%BCP_EXPORT_TABLE% out TableDataWithoutHeaders.csv -c -t, -T -S%BCP_EXPORT_SERVER%

set BCP_EXPORT_SERVER=
set BCP_EXPORT_DB=
set BCP_EXPORT_TABLE=

copy /b HeadersOnly.csv+TableDataWithoutHeaders.csv TableData.csv

del HeadersOnly.csv
del TableDataWithoutHeaders.csv

Обратите внимание: если вам нужно предоставить учетные данные, замените опцию -T на -U имя_пользователя -P мой_пароль

Преимущество этого метода заключается в том, что имена столбцов всегда синхронизируются с таблицей с помощью INFORMATION_SCHEMA.COLUMNS.Недостатком является то, что он создает временные файлы.Microsoft действительно следует исправить утилиту bcp, чтобы обеспечить эту поддержку.

В этом решении используется трюк объединения строк SQL из здесь в сочетании с идеями BCP из здесь

Хорошей альтернативой является SqlCmd, поскольку он включает заголовки, но у него есть недостаток: добавление пробелов вокруг данных для удобства чтения человеком.Вы можете объединить SqlCmd с утилитой GnuWin32 sed (редактирование потока) для очистки результатов.Вот пример, который сработал у меня, хотя я не могу гарантировать, что он надежен.

Сначала экспортируйте данные:

sqlcmd -S Server -i C:\Temp\Query.sql -o C:\Temp\Results.txt -s"    "

А -s" " — символ табуляции в двойных кавычках.Я обнаружил, что вам нужно запускать эту команду через пакетный файл, иначе командная строка Windows будет рассматривать вкладку как команду автоматического завершения и подставит имя файла вместо вкладки.

Если Query.sql содержит:

SELECT name, object_id, type_desc, create_date
FROM MSDB.sys.views
WHERE name LIKE 'sysmail%'

то вы увидите что-то подобное вResult.txt

name                                          object_id   type_desc           create_date            
-------------------------------------------   ----------- ------------------- -----------------------
sysmail_allitems                               2001442204 VIEW                2012-07-20 17:38:27.820
sysmail_sentitems                              2017442261 VIEW                2012-07-20 17:38:27.837
sysmail_unsentitems                            2033442318 VIEW                2012-07-20 17:38:27.850
sysmail_faileditems                            2049442375 VIEW                2012-07-20 17:38:27.860
sysmail_mailattachments                        2097442546 VIEW                2012-07-20 17:38:27.933
sysmail_event_log                              2129442660 VIEW                2012-07-20 17:38:28.040

(6 rows affected)

Затем проанализируйте текст с помощью sed:

sed -r "s/ +\t/\t/g" C:\Temp\Results.txt | sed -r "s/\t +/\t/g" | sed -r "s/(^ +| +$)//g" | sed 2d | sed $d | sed "/^$/d" > C:\Temp\Results_New.txt

Обратите внимание, что 2d команда означает удаление второй строки, $d команда означает удаление последней строки, а "/^$/d" удаляет все пустые строки.

Очищенный файл выглядит так (хотя я заменил вкладки на | чтобы их можно было визуализировать здесь):

name|object_id|type_desc|create_date
sysmail_allitems|2001442204|VIEW|2012-07-20 17:38:27.820
sysmail_sentitems|2017442261|VIEW|2012-07-20 17:38:27.837
sysmail_unsentitems|2033442318|VIEW|2012-07-20 17:38:27.850
sysmail_faileditems|2049442375|VIEW|2012-07-20 17:38:27.860
sysmail_mailattachments|2097442546|VIEW|2012-07-20 17:38:27.933
sysmail_event_log|2129442660|VIEW|2012-07-20 17:38:28.040

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

Пакетный файл, инициирующий bcp, содержит строку в нижней части сценария, выполняющую другой сценарий, объединяющий файл шаблона с именами заголовков и файл, который был только что экспортирован с помощью bcp с использованием приведенного ниже кода.Надеюсь, это поможет кому-то еще, кто был в моей ситуации.

echo Add headers from template file to exported sql files....
Echo School 0031
copy e:\genin\templates\TEMPLATE_Courses.csv + e:\genin\0031\courses0031.csv e:\genin\finished\courses0031.csv /b

У меня была та же проблема.Мне нужно было экспортировать заголовок столбца с помощью утилиты SQL Server bcp. Таким образом, я экспортировал «заголовки» таблицы с данными в тот же экспортированный файл за один раз.

DECLARE @table_name  VARCHAR(50) ='mytable'
DECLARE @columnHeader VARCHAR(8000)
SELECT @columnHeader = COALESCE(@columnHeader+',' ,'')+ ''''+column_name +'''' FROM Nal2013.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=@table_name
SELECT @raw_sql = 'bcp "SELECT '+ @columnHeader +' UNION ALL SELECT * FROM mytable" queryout c:\datafile.csv -c -t, -T -S '+ @@servername
EXEC  xp_cmdshell @raw_sql

Приятного кодирования :)

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

Одним из распространенных методов решения этой проблемы является использование представления фактических данных для экспорта, которое по сути выполняет UNION ALL для двух операторов:

  • первый оператор, возвращающий одну строку с заголовками столбцов
  • фактические данные для экспорта

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

Марк

Помимо решения от marc_s, вы также можете использовать osql или sqlcmd

Это включает в себя заголовки и может действовать как bcp, используя -Q и -o.Однако они не поддерживают файлы форматов, такие как bcp.

Вот довольно простая хранимая процедура, которая тоже делает свое дело.

    CREATE PROCEDURE GetBCPTable
    @table_name varchar(200)
AS
BEGIN
    DECLARE @raw_sql nvarchar(3000)

    DECLARE @columnHeader VARCHAR(8000)
    SELECT @columnHeader = COALESCE(@columnHeader+',' ,'')+ ''''+column_name +'''' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table_name

    DECLARE @ColumnList VARCHAR(8000)
    SELECT @ColumnList = COALESCE(@ColumnList+',' ,'')+ 'CAST('+column_name +' AS VARCHAR)' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table_name

    SELECT @raw_sql = 'SELECT '+ @columnHeader +' UNION ALL SELECT ' + @ColumnList + ' FROM ' + @table_name 
    --PRINT @raw_SQL
    EXECUTE sp_executesql  @raw_sql
END
GO

Все версии действуют немного по-разному.Это версия, которую я разрабатывал годами.Кажется, эта версия учитывает все проблемы, с которыми я столкнулся.Просто заполните набор данных в таблице, а затем передайте имя таблицы этой хранимой процедуре.

Я вызываю эту хранимую процедуру следующим образом:

EXEC    @return_value = *DB_You_Create_The_SP_In*.[dbo].[Export_CSVFile]
        @DB = N'*YourDB*',
        @TABLE_NAME = N'*YourTable*',
        @Dir = N'*YourOutputDirectory*',
        @File = N'*YourOutputFileName*'

Есть еще две переменные:

  • @Nullblanks - это займет любое поле, которое не имеет значения и его нуля.Это полезно, потому что в истинном смысле спецификации CSV каждая точка данных должна иметь цитаты вокруг них.Если у вас есть большой набор данных, это сэкономит вам достаточно места, не имея «» (две двойные цитаты) в этих областях.Если вы не находите это полезным, установите значение 0.
  • @Includeheaders - у меня есть одна хранящаяся процедура для вывода файлов CSV, поэтому у меня есть этот флаг в случае, если я не хочу заголовков.

Это создаст хранимую процедуру:

CREATE PROCEDURE [dbo].[Export_CSVFile] 
(@DB varchar(128),@TABLE_NAME varchar(128), @Dir varchar(255), @File varchar(250),@NULLBLANKS bit=1,@IncludeHeader bit=1)
AS

DECLARE @CSVHeader varchar(max)=''  --CSV Header
, @CmdExc varchar(max)=''           --EXEC commands
, @SQL varchar(max)=''              --SQL Statements
, @COLUMN_NAME varchar(128)=''      --Column Names
, @DATA_TYPE varchar(15)=''         --Data Types

DECLARE @T table (COLUMN_NAME varchar(128),DATA_TYPE varchar(15))

--BEGIN Ensure Dir variable has a backslash as the final character
IF NOT RIGHT(@Dir,1) = '\' BEGIN SET @Dir=@Dir+'\' END
--END

--BEGIN Drop TEMP Table IF Exists
SET @SQL='IF (EXISTS (SELECT * FROM '+@DB+'.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ''TEMP_'+@TABLE_NAME+''')) BEGIN EXEC(''DROP TABLE ['+@DB+'].[dbo].[TEMP_'+@TABLE_NAME+']'') END'
EXEC(@SQL)
--END

SET @SQL='SELECT COLUMN_NAME,DATA_TYPE FROM '+@DB+'.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='''+@TABLE_NAME+''' ORDER BY ORDINAL_POSITION'
INSERT INTO @T
EXEC (@SQL)

SET @SQL=''
WHILE exists(SELECT * FROM @T)
    BEGIN
        SELECT top(1) @DATA_TYPE=DATA_TYPE,@COLUMN_NAME=COLUMN_NAME FROM @T
        IF @DATA_TYPE LIKE '%char%' OR @DATA_TYPE LIKE '%text'
            BEGIN 
            IF @NULLBLANKS = 1
                BEGIN
                    SET @SQL+='CASE PATINDEX(''%[0-9,a-z]%'','+@COLUMN_NAME+') WHEN ''0'' THEN NULL ELSE ''"''+RTRIM(LTRIM('+@COLUMN_NAME+'))+''"'' END AS ['+@COLUMN_NAME+'],' 
                END
            ELSE
                BEGIN
                    SET @SQL+='''"''+RTRIM(LTRIM('+@COLUMN_NAME+'))+''"'' AS ['+@COLUMN_NAME+'],' 
                END
            END
        ELSE
            BEGIN SET @SQL+=@COLUMN_NAME+',' END
            SET @CSVHeader+='"'+@COLUMN_NAME+'",'
            DELETE top(1) @T
    END 

IF LEN(@CSVHeader)>1 BEGIN SET @CSVHeader=RTRIM(LTRIM(LEFT(@CSVHeader,LEN(@CSVHeader)-1))) END

IF LEN(@SQL)>1 BEGIN SET @SQL= 'SELECT '+ LEFT(@SQL,LEN(@SQL)-1) + ' INTO ['+@DB+'].[dbo].[TEMP_'+@TABLE_NAME+'] FROM ['+@DB+'].[dbo].['+@TABLE_NAME+']' END
EXEC(@SQL)

IF @IncludeHeader=0 
    BEGIN
        --BEGIN Create Data file
        SET  @CmdExc ='BCP "'+@DB+'.dbo.TEMP_'+@TABLE_NAME+'" out "'+@Dir+'Data_'+@TABLE_NAME+'.csv" /c /t, -T' 
        EXEC master..xp_cmdshell @CmdExc
        --END
        SET  @CmdExc ='del '+@Dir+@File EXEC master..xp_cmdshell @CmdExc
        SET  @CmdExc ='ren '+@Dir+'Data_'+@TABLE_NAME+'.csv '+@File EXEC master..xp_cmdshell @CmdExc
    END 
else
    BEGIN

        --BEGIN Create Header and main file
        SET  @CmdExc ='echo '+@CSVHeader+'> '+@Dir+@File EXEC master..xp_cmdshell @CmdExc
        --END

        --BEGIN Create Data file
        SET  @CmdExc ='BCP "'+@DB+'.dbo.TEMP_'+@TABLE_NAME+'" out "'+@Dir+'Data_'+@TABLE_NAME+'.csv" /c /t, -T' 
        EXEC master..xp_cmdshell @CmdExc
        --END

        --BEGIN Merge Data File With Header File
        SET @CmdExc = 'TYPE '+@Dir+'Data_'+@TABLE_NAME+'.csv >> '+@Dir+@File EXEC master..xp_cmdshell @CmdExc
        --END

        --BEGIN Delete Data File
        SET @CmdExc = 'DEL /q '+@Dir+'Data_'+@TABLE_NAME+'.csv' EXEC master..xp_cmdshell @CmdExc
        --END
    END
--BEGIN Drop TEMP Table IF Exists
SET @SQL='IF (EXISTS (SELECT * FROM '+@DB+'.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ''TEMP_'+@TABLE_NAME+''')) BEGIN EXEC(''DROP TABLE ['+@DB+'].[dbo].[TEMP_'+@TABLE_NAME+']'') END'
EXEC(@SQL)

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

CREATE VIEW [dbo].[vwxMySAMPLE_EXTRACT_COLUMNS]
  AS
    WITH MYBCP_CTE (COLUMN_NM, ORD_POS, TXT)
     AS
      ( SELECT  COLUMN_NAME
             , ORDINAL_POSITION
             , CAST(COLUMN_NAME AS VARCHAR(MAX))
        FROM [INFORMATION_SCHEMA].[COLUMNS]   
        WHERE TABLE_NAME = 'xMySAMPLE_EXTRACT_NEW'
        AND ORDINAL_POSITION = 1

        UNION ALL

        SELECT  V.COLUMN_NAME
              , V.ORDINAL_POSITION
              , CAST(C.TXT + '|' + V.COLUMN_NAME AS VARCHAR(MAX))
        FROM [INFORMATION_SCHEMA].[COLUMNS]  V INNER JOIN MYBCP_CTE C
        ON V.ORDINAL_POSITION = C.ORD_POS+1
        AND V.ORDINAL_POSITION > 1
        WHERE TABLE_NAME = 'xMySAMPLE_EXTRACT_NEW'
      )

      SELECT CC.TXT
      FROM MYBCP_CTE CC INNER JOIN ( SELECT MAX(ORD_POS) AS MX_CNT
                                     FROM MYBCP_CTE C
                                    ) SC
      ON CC.ORD_POS = SC.MX_CNT

Теперь создайте командный файл.Я создал это в своем каталоге Temp, но мне лень.

  cd\ 
  CD "C:\Program Files\Microsoft SQL Server\110\Tools\Binn"

  set buildhour=%time: =0%
  set buildDate=%DATE:~4,10%
  set backupfiledate=%buildDate:~6,4%%buildDate:~0,2%%buildDate:~3,2%%time:~0,2%%time:~3,2%%time:~6,2%

  echo %backupfiledate%
  pause

Приведенный выше код просто создает дату для добавления в конец вашего файла.Далее первый оператор bcp с целью рекурсивного cte объединить все это вместе.

  bcp "SELECT *  FROM [dbo].[vwxMYSAMPLE_EXTRACT_COLUMNS] OPTION (MAXRECURSION 300)" queryout C:\Temp\Col_NM%backupfiledate%.txt -c -t"|" -S MYSERVERTOLOGINTO -T -q
  bcp "SELECT *  FROM [myDBName].[dbo].[vwxMYSAMPLE_EXTRACT_NEW] " queryout C:\Temp\3316_PHYSDATA_ALL%backupfiledate%.txt -c -t"|" -S MYSERVERTOLOGINTO -T -q

Теперь объедините их вместе с помощью команды копирования.

  copy C:\Temp\Col_NM%backupfiledate%.txt  + C:\Temp\3316_PHYSDATA_ALL%backupfiledate%.txt  C:\Temp\3316_PHYSDATA_ALL%backupfiledate%.csv

Все готово

В последней версии sqlcmd добавлена -w возможность убрать лишний пробел после значения поля;однако строки НЕ заключаются в кавычки, что может стать проблемой для CSV при импорте значения поля, содержащего запятую.

У меня есть версия, основанная на том, что я видел ранее.Мне очень помогло создание файлов экспорта в формате CSV или TXT.Я сохраняю таблицу в ## Temp Table:

    IF OBJECT_ID('tempdb..##TmpExportFile') IS NOT NULL
DROP TABLE ##TmpExportFile;


DECLARE @columnHeader VARCHAR(8000)
DECLARE @raw_sql nvarchar(3000)

SELECT
              * INTO ##TmpExportFile
              ------ FROM THE TABLE RESULTS YOU WANT TO GET
              ------ COULD BE A TABLE OR A TEMP TABLE BASED ON INNER JOINS
              ------ ,ETC.

FROM TableName -- optional WHERE ....


DECLARE @table_name  VARCHAR(50) = '##TmpExportFile'
SELECT
              @columnHeader = COALESCE(@columnHeader + ',', '') + '''[' + c.name + ']''' + ' as ' + '' + c.name + ''
FROM tempdb.sys.columns c
INNER JOIN tempdb.sys.tables t
              ON c.object_id = t.object_id
WHERE t.NAME = @table_name

print @columnheader

                DECLARE @ColumnList VARCHAR(max)
SELECT
              @ColumnList = COALESCE(@ColumnList + ',', '') + 'CAST([' + c.name + '] AS CHAR(' + LTRIM(STR(max_length)) + '))'
FROM tempdb.sys.columns c
INNER JOIN tempdb.sys.tables t
              ON c.object_id = t.object_id
WHERE t.name = @table_name
print @ColumnList

--- CSV FORMAT                                       
SELECT
              @raw_sql = 'bcp "SELECT ' + @columnHeader + ' UNION all SELECT ' + @ColumnList + ' FROM ' + @table_name + ' " queryout \\networkdrive\networkfolder\datafile.csv -c -t, /S' + ' SQLserverName /T'
--PRINT @raw_sql
EXEC xp_cmdshell @raw_sql

  --- TXT FORMAT
       SET @raw_sql = 'bcp "SELECT ' + @columnHeader + ' UNION all SELECT ' + @ColumnList + ' FROM ' + @table_name + ' " queryout \\networkdrive\networkfolder\MISD\datafile.txt /c /S'+ ' SQLserverName /T'
       EXEC xp_cmdshell @raw_sql



DROP TABLE ##TmpExportFile

Я успешно достиг этого с помощью приведенного ниже кода.Поместите приведенный ниже код в окно нового запроса SQL Server и попробуйте

CREATE TABLE tempDBTableDetails ( TableName VARCHAR(500), [RowCount] VARCHAR(500), TotalSpaceKB VARCHAR(500),
                UsedSpaceKB VARCHAR(500), UnusedSpaceKB VARCHAR(500) )

    -- STEP 1 :: 
    DECLARE @cmd VARCHAR(4000)

INSERT INTO tempDBTableDetails
SELECT 'TableName', 'RowCount', 'TotalSpaceKB', 'UsedSpaceKB', 'UnusedSpaceKB'
INSERT INTO tempDBTableDetails
SELECT  
    S.name +'.'+ T.name as TableName, 
    Convert(varchar,Cast(SUM(P.rows) as Money),1) as [RowCount],
    Convert(varchar,Cast(SUM(a.total_pages) * 8 as Money),1) AS TotalSpaceKB, 
    Convert(varchar,Cast(SUM(a.used_pages) * 8 as Money),1) AS UsedSpaceKB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM sys.tables T
INNER JOIN sys.partitions P ON P.OBJECT_ID = T.OBJECT_ID
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
INNER JOIN sys.allocation_units A ON p.partition_id = a.container_id
WHERE T.is_ms_shipped = 0 AND P.index_id IN (1,0)
GROUP BY S.name, T.name
ORDER BY SUM(P.rows) DESC

-- SELECT * FROM [FIINFRA-DB-SIT].dbo.tempDBTableDetails ORDER BY LEN([RowCount]) DESC

SET @cmd = 'bcp "SELECT * FROM [FIINFRA-DB-SIT].dbo.tempDBTableDetails ORDER BY LEN([RowCount]) DESC" queryout "D:\Milind\export.xls" -U sa -P dbowner -c'
    Exec xp_cmdshell @cmd 

--DECLARE @HeaderCmd VARCHAR(4000)
--SET @HeaderCmd = 'SELECT ''TableName'', ''RowCount'', ''TotalSpaceKB'', ''UsedSpaceKB'', ''UnusedSpaceKB'''
exec master..xp_cmdshell 'BCP "SELECT ''TableName'', ''RowCount'', ''TotalSpaceKB'', ''UsedSpaceKB'', ''UnusedSpaceKB''" queryout "d:\milind\header.xls" -U sa -P dbowner -c'
exec master..xp_cmdshell 'copy /b "d:\Milind\header.xls"+"d:\Milind\export.xls" "d:/Milind/result.xls"'

exec master..xp_cmdshell 'del "d:\Milind\header.xls"'
exec master..xp_cmdshell 'del "d:\Milind\export.xls"'

DROP TABLE tempDBTableDetails 

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

CREATE PROCEDURE Export_Data_NBA
@TableName nchar(50),
@TableSchema nvarchar(50) = ''

AS
DECLARE @TableToBeExported as nvarchar(50);

DECLARE @OUTPUT TABLE (col1 nvarchar(max));
DECLARE @colnamestable VARCHAR(max);
select @colnamestable = COALESCE(@colnamestable, '') +COLUMN_NAME+ ','
from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName
order BY ORDINAL_POSITION

SELECT @colnamestable = LEFT(@colnamestable,DATALENGTH(@colnamestable)-1)

INSERT INTO @OUTPUT
select @colnamestable

DECLARE @selectstatement VARCHAR(max);
select @selectstatement = COALESCE(@selectstatement, '') + 'Convert(nvarchar(100),'+COLUMN_NAME+')+'',''+'
from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName
order BY ORDINAL_POSITION

SELECT @selectstatement = LEFT(@selectstatement,DATALENGTH(@selectstatement)-1)

DECLARE @sqlstatment as nvarchar(max);

SET @TableToBeExported = @TableSchema+'.'+@TableToBeExported

SELECT @sqlstatment = N'Select '+@selectstatement+N' from '+@TableToBeExported

INSERT INTO @OUTPUT
exec sp_executesql @stmt = @sqlstatment

SELECT * from @OUTPUT

С помощью небольшого скрипта PowerShell

sqlcmd -Q "set nocount on select top 0 * from [DB].[schema].[table]" -o c:\temp\header.txt 
bcp [DB].[schema].[table] out c:\temp\query.txt -c -T -S BRIZA
Get-Content c:\temp\*.txt | Set-Content c:\temp\result.txt
Remove-Item c:\temp\header.txt
Remove-Item c:\temp\query.txt

Предупреждение о том, что объединение следует за именем текстового файла (в алфавитном порядке).

Некоторые из решений здесь слишком сложны.Вот пример с 4 строками кода, без пакетных файлов, без внешних приложений, и все это автономно на SQL-сервере.

В этом примере моя таблица называется «MyTable» и имеет два столбца с именами Column1 и Column2.Столбец2 — целое число, поэтому для экспорта нам нужно привести его к varchar:

DECLARE @FileName varchar(100)
DECLARE @BCPCommand varchar(8000)
DECLARE @ColumnHeader varchar(8000)

    SET @FileName = 'C:\Temp\OutputFile.csv'
 SELECT @ColumnHeader = COALESCE(@ColumnHeader+',' ,'')+ ''''+column_name +'''' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='MyTable'
    SET @BCPCommand = 'bcp "SELECT '+ @ColumnHeader +' UNION ALL SELECT Column1, CAST(Column2 AS varchar(100)) AS Column2 FROM MyTable" queryout "' + @FileName + '" -c -t , -r \n  -S . -T'
   EXEC master..xp_cmdshell @BCPCommand

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

DECLARE @table_name varchar(max)='tableName'--which needs to be exported
DECLARE @fileName varchar(max)='file Name'--What would be file name

DECLARE @query varchar(8000)
DECLARE @columnHeader VARCHAR(max)
SELECT @columnHeader = COALESCE(@columnHeader+',' ,'')+ ''''+column_name +''''  FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table_name

DECLARE @ColumnList VARCHAR(max)
SELECT @ColumnList = COALESCE(@ColumnList+',' ,'')+ 'CAST('+column_name +' AS VARCHAR)' +column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table_name

DECLARE @tempRaw_sql nvarchar(max)
SELECT @tempRaw_sql = 'SELECT ' + @ColumnList + ' into ##temp11 FROM ' + @table_name 
PRINT @tempRaw_sql
EXECUTE sp_executesql  @tempRaw_sql


DECLARE @raw_sql nvarchar(max)
SELECT @raw_sql = 'SELECT  '+ @columnHeader +' UNION ALL SELECT * FROM ##temp11'
PRINT @raw_SQL
SET @query='bcp "'+@raw_SQL+'" queryout "C:\data\'+@fileName+'.txt" -T -c -t,'
EXEC xp_cmdshell @query


DROP TABLE ##temp11
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top