If you are looking for a generic way to export table data via BCP, here’s how:
CREATE PROCEDURE ExportDataViaBcp
(
@server VARCHAR(100) = '(local)',
@db VARCHAR(100),
@dbtable VARCHAR(100),
@file VARCHAR(200),
@fmt_date INT = 121,
@fmt_decimal INT = 128,
@fmt_money INT = 1,
@fmt_float INT = NULL
)
AS
SET NOCOUNT ON
-- sql that gets executed
DECLARE @tmpSql VARCHAR(8000)
-- in case we have an error
DECLARE @error VARCHAR(200)
-- USE the database
SELECT @tmpSql = 'USE ' + @db + ';'
PRINT @tmpSql
EXEC(@tmpSql)
-- Make sure the (global) temp tables have been cleaned up
IF OBJECT_ID('tempdb..##export_temp') IS NOT NULL
DROP TABLE ##export_temp
IF OBJECT_ID('tempdb..##export_temp2') IS NOT NULL
DROP TABLE ##export_temp2
-- Execute the use and the select
SELECT @tmpSql = 'SELECT * INTO ##export_temp FROM ' + @dbtable + ';'
PRINT @tmpSql
EXEC(@tmpSql)
-- Build 2 lists
-- 1. column names
-- 2. columns converted to nvarchar from their original type
DECLARE
@columnNames VARCHAR(MAX),
@columnConversions VARCHAR(MAX)
SELECT
@columnNames =
COALESCE(@columnNames + ',', '') +
'[' + column_name + ']',
@columnConversions =
COALESCE(@columnConversions + ',', '') +
'CONVERT(NVARCHAR(100),[' + column_name + ']' +
CASE
WHEN data_type IN ('NUMERIC', 'DECIMAL') THEN CASE WHEN @fmt_decimal IS NOT NULL THEN ',' + CONVERT(VARCHAR, @fmt_decimal) ELSE '' END
WHEN data_type IN ('MONEY', 'SMALLMONEY') THEN CASE WHEN @fmt_money IS NOT NULL THEN ',' + CONVERT(VARCHAR, @fmt_money) ELSE '' END
WHEN data_type IN ('DATETIME', 'SMALLDATETIME') THEN CASE WHEN @fmt_date IS NOT NULL THEN ',' + + CONVERT(VARCHAR, @fmt_date) ELSE '' END
WHEN data_type IN ('FLOAT', 'REAL') THEN CASE WHEN @fmt_float IS NOT NULL THEN ',' + + CONVERT(VARCHAR, @fmt_float) ELSE '' END
ELSE ''
END + ') AS [' + column_name + ']'
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE table_name = '##export_temp'
-- execute select query to insert data and column names into new temp table
SELECT @tmpSql =
'SELECT ' + @columnNames + ' ' +
'INTO ##export_temp2 ' +
'FROM ( ' +
' SELECT ' + @columnConversions + ', 2 AS tmpsort FROM ##export_temp ' +
' UNION ALL ' +
' SELECT ''' + REPLACE(REPLACE(REPLACE(@columnNames, ',', ''', '''),'[',''),']','') + ''', 1 AS tmpsort ' +
' ) AS x ' +
' ORDER BY x.tmpsort; ';
PRINT @tmpSql
EXEC(@tmpSql)
-- Execute the BCP to create the file
SELECT @tmpSql = 'bcp "SELECT * FROM ##export_temp2" queryout "' + @file + '" -c -CRAW -t, -T -S' + @server
EXEC master.sys.xp_cmdshell @tmpSql
IF @@ERROR > 0
BEGIN
IF OBJECT_ID('##export_temp') IS NOT NULL
DROP TABLE ##export_temp
IF OBJECT_ID('##export_temp2') IS NOT NULL
DROP TABLE ##export_temp2
SELECT @error = 'Couldn''t execute the bcp: ''' + @tmpSql;
RAISERROR(@error, 16, 1)
RETURN
END
-- Make sure the (global) temp tables have been cleaned up
IF OBJECT_ID('tempdb..##export_temp') IS NOT NULL
DROP TABLE ##export_temp
IF OBJECT_ID('tempdb..##export_temp2') IS NOT NULL
DROP TABLE ##export_temp2
GO
This does use global temp tables as well as xp_cmdshell, but it also gets the job done.
This is a modified version of the suggestion found here:
http://weblogs.sqlteam.com/mladenp/archive/2006/07/25/10771.aspx
Thanks to them for actually doing the hard work! I just cleaned it up and made it support varied column names.