BCP - Data duplication during export command - sql-server

I have a procedure which is for exporting data from table to .DAT file. There's a job running on it which calls SP every 10 Min. .DAT file contains H= column names, B= table data, T= No of rows processed(.SIG file appends this to .DAT file).
Following is the stored procedure :
CREATE PROCEDURE [dbo].[Test_Export] #count2 VARCHAR(10)
AS
BEGIN
SET NOCOUNT ON;
--Alerts_Balance
DECLARE #bcp_sql VARCHAR(1000)
DECLARE #filename VARCHAR(200), #count1 VARCHAR(10)=20000
SET #filename = 'C:\Test'+'.DAT';
SELECT #bcp_sql = 'bcp "SELECT ''H'',''Name'',''City'',''State'',''Country'' union all SELECT top 10 ''B'', [Name],[City],[State],[Country] FROM Test_Table" queryout ' + #filename + ' -c -t, -T -S '+ ##servername
EXEC master.sys.xp_cmdshell #bcp_sql
SELECT #bcp_sql = 'bcp "SELECT ''T'', '+cast(IIF(cast(#count1 as int)>cast(#count2 as int), #count2+2, #count1+2) as varchar(10))+'" queryout '+ #filename + '.sig -c -t, -T -S '+ ##servername
EXEC master.sys.xp_cmdshell #bcp_sql
SELECT #bcp_sql = 'type ' + #filename + '.sig >> "' + #filename + '"'
EXEC master.sys.xp_cmdshell #bcp_sql
SELECT #bcp_sql = 'copy nul: ' + #filename + '.sig'
EXEC master.sys.xp_cmdshell #bcp_sql
EXEC (#bcp_sql);
END
It was working fine before with proper data format in .dat.
From couple of days, sometimes .dat file contain no "B" (body) data. Sometimes SIG file appends T 2 times to .DAT file on PROD environment. Sometimes it gives correct output also. This issue is coming only on PROD environment
Any idea why it is behaving like this?

Related

SQL BCP Export XML To UTF-8 Format

I have a query that executes a stored procedure and exports the results to an XML file via BCP. The process works, except that the encoding of the XML file is showing as UCS-2 and I am told that the system I will be importing it into needs it to be UTF-8. Various threads suggest this should be possible, but I can't seem to find the right syntax. My code below...
ALTER PROCEDURE [dbo].[cli_sel_c4t_supplier_report]
#Consignment_id decimal(18,0),
#Supplier decimal(18,0),
#Username varchar(50)
AS
BEGIN
DECLARE #fileName VARCHAR(50),
#sqlCmd VARCHAR(8000),
#sqlStr Varchar(8000)
SET #fileName = 'C:\C4T\' + CONVERT(VARCHAR(10), #Consignment_id) + CONVERT(VARCHAR(20), #Supplier) + '.xml';
SET #sqlStr='EXEC [Company Database].[dbo].[cli_sel_c4t_xml_data] #Consignment_id = ' + CONVERT(VARCHAR(10), #Consignment_id) + ', #Supplier = ' + CONVERT(VARCHAR(12), #Supplier) + ';';
SET #sqlCmd = 'bcp "' + #sqlStr + '" queryout ' + #fileName + ' -c -C65001 -T -S "SVRNAME\INSTANCE"';
EXEC cli_ins_audit_c4t_file #Consignment_id=#Consignment_id, #Supplier_id=#Supplier, #Path=#fileName, #Username=#Username
EXEC xp_cmdshell #sqlCmd;
END
Any assistance would be appreciated.
Thanks
Steve
To generate UTF-8 instead of UTF-16, use -c instead of -w parameter. The -c option in bcp export characters by single byte.
Explicitly specifying code page 1252, and UTF-8: -c -C 1252

BCP file name as datetime stamp

I am trying to crate a CSV export file using BCP with a the datetime stamp in the file name. Everything appears correct but I keep getting errors around the + sign.
BEGIN
SET NOCOUNT ON
DECLARE #mydate DATETIME
DECLARE #filename VARCHAR(40)
SET #mydate = GETDATE()
SET #filename = 'C:\TEMP\TEST-'+CONVERT(varchar,FORMAT(#mydate,'yyyyMMdd-
hhmmss'))+'.csv'
exec master..xp_cmdshell 'bcp "select
CHAR(34)+""SampleNo""+CHAR(34),CHAR(34)+""Analysis
Code""+CHAR(34),CHAR(34)+""Analyte Name""+CHAR(34),CHAR(34)+""Old
Result""+CHAR(34),CHAR(34)+""New
Result""+CHAR(34),CHAR(34)+""ChangeDate""+CHAR(34)+CHAR(44) union all
SELECT CHAR(34)+SAMPNO+CHAR(34), CHAR(34)+ACODE+CHAR(34),
CHAR(34)+ANLNAME+CHAR(34), CHAR(34)+OLDRESULT+CHAR(34),
CHAR(34)+NEWRESULT+CHAR(34), CHAR(34)+CHANGEDATE+CHAR(34)+CHAR(44)
FROM TEST.dbo.MODIFY_EXPORT" QUERYOUT ' + #filename + ' -S SERV2012R2 -U sa -P password -c -t","'
END;

Exporting all tables into files from SQL Server database using utility bulk copy

I want to bcp all tables into files from a database:
SELECT 'EXEC xp_cmdshell ''bcp ' --bcp
+ QUOTENAME(DB_NAME())+ '.' --database name
+ QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+ '.' -- schema
+ QUOTENAME(name) -- table
+ ' out c:\temp\' -- output directory
+ REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
+ REPLACE(name,' ','') -- file name
+ '.txt -T -c''' -- extension, security
FROM sys.tables
it produces statements like this:
EXEC xp_cmdshell 'bcp [AdventureWorks2012].[Production].[ScrapReason] out c:\temp\Production_ScrapReason.txt -T -c'
EXEC xp_cmdshell 'bcp [AdventureWorks2012].[HumanResources].[Shift] out c:\temp\HumanResources_Shift.txt -T -c'
so what I want is to iterate over above statements and execute all them. How to do this?
Note this assumes all commands are unique.
DECLARE #Commands TABLE(CommandText NVARCHAR(4000));
DECLARE #SQL NVARCHAR(4000);
INSERT INTO #Commands
SELECT 'EXEC xp_cmdshell ''bcp ' --bcp
+ QUOTENAME(DB_NAME())+ '.' --database name
+ QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+ '.' -- schema
+ QUOTENAME(name) -- table
+ ' out c:\temp\' -- output directory
+ REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
+ REPLACE(name,' ','') -- file name
+ '.txt -T -c''' -- extension, security
FROM sys.tables
WHILE (SELECT COUNT(*) FROM #Commands) > 0
BEGIN --Command Processing
SET #SQL = (SELECT TOP 1 CommandText FROM #Commands)
--PRINT (#SQL)
EXEC (#SQL)
DELETE FROM #Commands WHERE CommandText = #SQL
END
Default setting is that you can't execute bcp command from SQL server. This version works from DOS, Powershell and BAT file.
I didn't find setting from BCP which would export the heading line on these CSV files, so note that these CSV files don't include heading.
-- Run this command to the database you wish to export
DECLARE #Commands TABLE(CommandText NVARCHAR(4000));
DECLARE #SQL NVARCHAR(4000);
INSERT INTO #Commands
SELECT 'bcp ' --bcp
+ QUOTENAME(DB_NAME())+ '.' --database name
+ QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+ '.' -- schema
+ QUOTENAME(name) -- table
+ ' out c:\temp\csvdump\' -- output directory
+ REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
+ REPLACE(name,' ','') -- file name
+ '.csv -T -C 65001 -t "|" -k -c -S localhost' -- extension, security
FROM sys.tables
-- Copy-paste results to DOS or Powershell prompt or create a BAT file from these.
SELECT 'mkdir c:\temp\csvdump'
UNION ALL
SELECT * FROM #Commands

SQL Server output to a file using variable name

I want to send SQL Server output to a file which is working as expected. But if I pass the file path in a variable, It is not creating the file.
Working
:out 'C:\Temp.txt'
Not Working
DECLARE #BCVFileName VARCHAR(500)
SET #BCVFileName= 'C:\Temp.txt'
:out #BCVFileName
Could anyone please help me on this??
Thanks,
Mahesh
For this you need to store your query in Query file and then you can execute from command to store result to a text file as shown below.
>sqlcmd -E -S(Local)\SQLExpress -YourDBName -iC:\myQuery -oC:\Output.txt
Another way to use T-SQL and create a batch statement to execute via XP_CMDSHELL. Following script will help you to do the same just replace your query, ServerName with used variables.
SET NOCOUNT ON;
GO
DECLARE #sqlcmd varchar(1000);
PRINT 'using SqlCMD.exe';
SET #sqlcmd = 'sqlcmd -S' + ##SERVERNAME + ' -E -oc:\outfile.txt '
DECLARE #cmd varchar(1000);
SET #cmd = '-Q"SELECT RIGHT(REPLICATE('' '' , 6) + CONVERT(varchar, AddressID), 6 ) AS AddressID, CONVERT(varchar(10), ModifiedDate, 121) AS ModifiedDate FROM AdventureWorks.Person.Address ORDER BY ModifiedDate;"';
SET #sqlcmd = #sqlcmd + #cmd;
--SELECT #sqlcmd;
EXEC xp_cmdshell #sqlcmd, no_output;
PRINT 'using BCP.exe';
SET #cmd = '"SELECT RIGHT(REPLICATE('' '' , 6) + CONVERT(varchar, AddressID), 6 ) AS AddressID, CONVERT(varchar(10), ModifiedDate, 121) AS ModifiedDate FROM AdventureWorks.Person.Address ORDER BY ModifiedDate;"';
SET #sqlcmd = 'bcp ' + #cmd + ' queryout "c:\outfile2.txt" -c -T -S' + ##SERVERNAME
--SELECT #sqlcmd;
EXEC xp_cmdshell #sqlcmd, no_output;
regards

Exporting stored procedure result to excel with column name

I have attached the code for storing the stored procedure output to an Excel sheet..
but I have few issues, they are
(1) all the columns are displayed in the first column of the excel sheet..which I don't need, I need to show the report in diff columns.. how to do that..
(2) if I use inner join with the main, how can I get the column names of the other table
Can anyone please help me out to solve the above issues?
alter procedure proc_generate_excel_with_columns
(
#db_name varchar(100),
#schm_name varchar(100),
#table_name varchar(100),
#file_name varchar(100)
)
as
--Generate column names as a recordset
declare #columns varchar(8000), #sql varchar(8000), #data_file varchar(100)
select
#columns = coalesce(#columns+',', '') + column_name + ' as ' + column_name
from
information_schema.columns
where
table_name = #table_name
select
#columns = '''' + replace(replace(#columns, ' as ', ''' as '),',',',''')
--Create a dummy file to have actual data
select
#data_file = substring(#file_name, 1, len(#file_name) -
charindex('\', reverse(#file_name))) + '\data_file.xls'
--Generate column names in the passed EXCEL file
set #sql='bcp " select * from (select ' + #columns + ') as t" queryout
c:\test.xls -c -t, -T -S ' + ##servername
exec master..xp_cmdshell #sql
--Generate data in the dummy file
set #sql = 'bcp "select * from st..VEN_FULLREPORTMASTER
where entry_date = convert(varchar, getdate() - 3, 105) "
queryout c:\data_file.xls -c -t, -T -S' + ##servername
-- exec master..xp_cmdshell #sql
-- Copy dummy file to passed EXCEL file
set #sql = 'exec master..xp_cmdshell ''type '+#data_file+' >> "'+#file_name+'"'''
exec(#sql)
----Delete dummy file
set #sql = 'exec master..xp_cmdshell ''del ' + #data_file + ''''
exec(#sql)
If using SSIS is an option this would be a trivial task to complete using a data flow task.
Can you use SSIS or do you need a pure tSQL solution?

Resources