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

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

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

bcp myschema.dbo.myTableout myTable.csv /SmyServer01 /c /t, -T

Ответы [ 15 ]

43 голосов
/ 18 марта 2012

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

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

Окончательный вывод объединяется в 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 my_username -P my_password

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

В этом решении используется прием конкатенации строк SQL из здесь в сочетании с идеями bcp из здесь

40 голосов
/ 15 марта 2011

Самым простым является использование опции 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
9 голосов
/ 16 октября 2013

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

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

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%'

тогда вы увидите нечто подобное в Results.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
6 голосов
/ 09 мая 2012

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

Пакетный файл, который запускает 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
3 голосов
/ 24 июня 2014

У меня была такая же проблема. Мне нужно было экспортировать заголовок столбца с помощью утилиты 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

Удачного кодирования:)

2 голосов
/ 24 августа 2016

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

    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
2 голосов
/ 31 августа 2009

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

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

2 голосов
/ 31 августа 2009

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

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

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

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

Марк

1 голос
/ 23 октября 2018

Я получил версию, основанную на том, что я видел ранее. Это очень помогло мне создать файлы экспорта в формате 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
1 голос
/ 14 декабря 2017

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

...