BCP file name as datetime stamp - sql-server

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;

Related

BCP - Data duplication during export command

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?

BCP export to XML, opening XML gives error: Extra content at the end of the document

I´m trying to export to XML format using BCP and the XML file is generated correctly but the actual content seems wrong. Can anyone help please?
When I try to open the XML in a browser I get the following error message:
This page contains the following errors: error on line 1 at column 62:
Extra content at the end of the document
The SQL select that I'm using is:
DECLARE #fileName VARCHAR(50)
DECLARE #sqlStr VARCHAR(1000)
DECLARE #sqlCmd VARCHAR(1000)
SET #fileName = 'c:\fund_lib\test.xml'
USE PORT_APP_SQL
DROP TABLE ##temp;
WITH cte1
AS (SELECT LTRIM(RTRIM(codigo)) AS code,
CONVERT(VARCHAR(10), fecha, 120) AS date,
precio AS NAV
FROM mpr_price_history
WHERE codigo IN( 'LU0038743380', 'LU0086913042', 'LU0265291665', 'LU0098860363',
'LU0128525689', 'LU0121204944', 'CZ0008474780', 'LU0363630376',
'LU0372180066', 'LU0271663857', 'LU0271663774', 'LU0363630707', 'LU0313643024' ))
SELECT *
INTO ##temp
FROM cte1
SET #sqlStr = 'select * from ##temp order by code, date desc FOR XML RAW (''code'');'
-- Save XML records to a file:
SET #sqlCmd = 'bcp "' + #sqlStr + '" queryout ' + #fileName
+ ' -S "MPR01\SQLEXPRESS" -T -w'
EXEC xp_cmdshell #sqlCmd
And this is the error message if I open it in Firefox ( sorry is in Spanish).
error message seems to be at the end of each line
I think that your whole query can be simplified... No need for a CTE or a temp table...
attention The solution for your problem is - probably! - the missing root node, as mentioned by #TT.. If adding a root node solves your problem, please do not accept my answer (although you might vote it up, if you like it :-) ).
Your problem might be bound to a mix of encodings. If your output includes special characters, there could be some problems when you mix 8-byte encoding (VARCHAR) and the output with option -w. Therefore I put this all in NVARCHAR(MAX)
My suggestion to get things slim:
USE PORT_APP_SQL;
DECLARE #fileName NVARCHAR(50) = 'c:\fund_lib\test.xml';
DECLARE #cmd NVARCHAR(MAX);
SET #cmd =
N'SELECT LTRIM(RTRIM(codigo)) AS code
,CONVERT(VARCHAR(10), fecha, 120) AS [date]
,precio AS NAV
FROM mpr_price_history
WHERE codigo IN( ''LU0038743380'', ''LU0086913042'', ''LU0265291665'', ''LU0098860363'',
''LU0128525689'', ''LU0121204944'', ''CZ0008474780'', ''LU0363630376'',
''LU0372180066'', ''LU0271663857'', ''LU0271663774'', ''LU0363630707'', ''LU0313643024'' )
ORDER BY code,[date] DESC
FOR XML RAW(''code''),ROOT(''root'');'
-- Save XML records to a file:
SET #cmd = N'bcp "' + #cmd + N'" queryout ' + #fileName
+ N' -S "MPR01\SQLEXPRESS" -T -w'
EXEC xp_cmdshell #cmd;
The reason is because the XML doesn't have a root path. This example based on your script should produce XML for which the browser doesn't complain:
DECLARE #fileName VARCHAR(50);
DECLARE #sqlStr VARCHAR(1000);
DECLARE #sqlCmd VARCHAR(1000);
SET #fileName = 'c:\temp\test.xml';
SELECT *
INTO ##temp
FROM (VALUES('LU0038743380',GETDATE(),1),
('LU0086913042',GETDATE(),2),
('LU0265291665',GETDATE(),3),
('LU0098860363',GETDATE(),4)) AS cte1(fecha,[date],nav);
SET #sqlStr = 'select (select * from ##temp FOR XML RAW(''code''),TYPE) FOR XML PATH(''data'');'
-- Save XML records to a file:
SET #sqlCmd = 'bcp "' + #sqlStr + '" queryout ' + #fileName
+ ' -S '+##SERVERNAME+' -T -w';
EXEC xp_cmdshell #sqlCmd;
DROP TABLE ##temp;
I have ran your code with small alterations with no errors.
It seems the issue is with your data.
Look for special XML characters.

Create .txt file out from SQL statement

I try to make a SQL statement to create a .txt file for each id that added to database, but this not working. I try this:
DECLARE #FileName varchar(50), #bcpCommand varchar(2000)
SET #FileName = REPLACE('G:\'+CONVERT(char(8),GETDATE(),1)+'.txt','/','-')
SET #bcpCommand = 'bcp "SELECT * FROM dbo.dbTest WHERE (DATEADD(MINUTE,-1420, GETDATE())) < [date];" queryout "'
SET #bcpCommand = #bcpCommand + #FileName + '" -U garth -P pw -c'
PRINT #bcpCommand
and of course I need this result savede in G:/, but this not working for me. My db name are testDB
Did you mean you want to create a bcp file for each database? Simply loop over all the databases, and ensure you specify the database name parameter for your bcp statement so it knows what database to execute the queryout query in. One other thing you will need to fix though, is the filename. You can modify it below to append the db name to the output file, so you do not end up overwriting each results.
DECLARE #FileName varchar(50), #bcpCommand varchar(2000)
declare #x int = 5
declare #y int
declare #dbname varchar(100)
select #y = max(database_id) from sys.databases
while #x <= #y
begin
select #dbname = name from sys.databases where database_id = #x
if #dbname is not null
begin
SET #FileName = REPLACE('G:\'+CONVERT(char(8),GETDATE(),1) +'.txt','/','-')
SET #bcpCommand = 'bcp "SELECT * FROM dbo.dbTest WHERE (DATEADD(MINUTE,-1420, GETDATE())) < [date];" queryout "'
SET #bcpCommand = #bcpCommand + #FileName + '" -U garth -P pw -c -d"' + #dbname + '"'
PRINT #bcpCommand
end
set #x = #x + 1
end
Sample results:
bcp "SELECT * FROM dbo.dbTest WHERE (DATEADD(MINUTE,-1420, GETDATE())) < [date];" queryout "G:\05-16-15.txt" -U garth -P pw -c -d"db1"
bcp "SELECT * FROM dbo.dbTest WHERE (DATEADD(MINUTE,-1420, GETDATE())) < [date];" queryout "G:\05-16-15.txt" -U garth -P pw -c -d"db2"
bcp "SELECT * FROM dbo.dbTest WHERE (DATEADD(MINUTE,-1420, GETDATE())) < [date];" queryout "G:\05-16-15.txt" -U garth -P pw -c -d"db3"
bcp "SELECT * FROM dbo.dbTest WHERE (DATEADD(MINUTE,-1420, GETDATE())) < [date];" queryout "G:\05-16-15.txt" -U garth -P pw -c -d"db4"

How to name column with BCP?

I have created this code in a stored procedure, it works like a charm: but now my software provider asked me to also include column name. Have tried 100 things for hours now always close but never get success. can anyone help me.
Thank you !
-- =============================================
-- Author: <blablabla>
-- Create date: <2014/04/16>
-- Description: <Export Orders to csv>
-- =============================================
ALTER PROCEDURE [dbo].[transfertofile]
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #return_value int
IF EXISTS (Select 1 From dbo.temp_updated)
BEGIN
DECLARE #sql varchar (8000)
SELECT #sql ='bcp "Select Detail, SectionRelease, 1, WMS80.dbo.temp_updated.OrderNumber, WMS80.dbo.PickingDetail.LineNumber, WMS80.dbo.PickingDetail.ItemNumber, CAST(WMS80.dbo.PickingDetail.ActualQuantity AS NUMERIC(10)), WMS80.dbo.temp_updated.UDF01, WMS80.dbo.temp_updated.UDF02, WMS80.dbo.PickingDetail.PickFrom FROM WMS80.dbo.temp_updated, WMS80.dbo.PickingDetail WHERE WMS80.dbo.temp_updated.OrderNumber = WMS80.dbo.PickingDetail.OrderNumber" queryout "C:\bcptest.txt" -U user -P password -c -S servername -t,'
EXEC xp_cmdshell #sql
--delete at the end
TRUNCATE TABLE WMS80.dbo.temp_updated
DECLARE
#TodayDate as varchar(40),
#TodayHour as varchar(40),
#TodayMinu as varchar(40),
#TodaySeco as varchar(40),
#NewFileName as varchar(100),
#cmdstr as varchar(128)
SELECT #TodayDate = CONVERT(varchar(10), GETDATE(), 112)
SELECT #TodayHour = DATEPART(hh,GETDATE())
SELECT #TodayMinu = DATEPART(mi,GETDATE())
SELECT #TodaySeco = DATEPART(SS,GETDATE())
SELECT #NewFileName = 'ExportOrders' + '_' + #TodayDate + '_' + #TodayHour + '_' + #TodayMinu + '_' + #TodaySeco + '.csv'
print #NewFileName
set #cmdstr='MOVE /Y C:\bcptest.txt C:\' + #NewFileName
print #cmdstr
EXEC master..xp_cmdshell #cmdstr
END
else
BEGIN
return
end
Use a UNION statement in your bcp query to hardcode the column names into the output file. This means of course you will have to export everything as varchar/string, since every column is going to contain its name in varchar format as a first entry.
#sql ='bcp "SELECT 'Detail', 'SectionRelease', '1', 'OrderNumber', 'LineNumber','ItemNumber', 'ActualQuantity', 'UDF01', 'UDF02', 'PickFrom', 'PickingDetail'
UNION SELECT Detail, SectionRelease, 1, WMS80.dbo.temp_updated.OrderNumber, WMS80.dbo.PickingDetail.LineNumber, WMS80.dbo.PickingDetail.ItemNumber, WMS80.dbo.PickingDetail.ActualQuantity, WMS80.dbo.temp_updated.UDF01, WMS80.dbo.temp_updated.UDF02, WMS80.dbo.PickingDetail.PickFrom FROM WMS80.dbo.temp_updated, WMS80.dbo.PickingDetail WHERE WMS80.dbo.temp_updated.OrderNumber = WMS80.dbo.PickingDetail.OrderNumber" queryout "C:\bcptest.txt" -U user -P password -c -S servername -t,'

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

Resources