22

Below is an example of the BCP Statement. I'm not accustomed to using BCP so your help and candor is greatly appreciated

I am using it with a format file as well.

If I execute from CMD prompt it works fine but from SQL I get the error. The BCP statement is all on one line and the SQL Server Agent is running as Local System. The SQL server, and script are on the same system.

I ran exec master..xp_fixeddrives C,45589 E,423686

I've tried output to C and E with the same result

EXEC xp_cmdshell 'bcp "Select FILENAME, POLICYNUMBER, INSURED_DRAWER_100, POLICY_INFORMATION, DOCUMENTTYPE, DOCUMENTDATE, POLICYYEAR FROM data.dbo.max" queryout "E:\Storage\Export\Data\max.idx" -fmax-c.fmt -SSERVERNAME -T

Here is the format file rmax-c.fmt

10.0

7

1      SQLCHAR             0       255     "$#Y#$"          1     FILENAME                               
2      SQLCHAR             0       40      ""               2     POLICYNUMBER                                 
3      SQLCHAR             0       40      ""               3     INSURED_DRAWER_100                           
4      SQLCHAR             0       40      ""               4     POLICY_INFORMATION                           
5      SQLCHAR             0       40      ""               5     DOCUMENTTYPE                                 
6      SQLCHAR             0       40      ""               6     DOCUMENTDATE                                 
7      SQLCHAR             0       8       "\r\n"           7     POLICYYEAR    

Due to formating in this post the last column of the format file is cut off but reads SQL_Latin1_General_CP1_CI_AS for each column other that documentdate.

Stanley Mungai
  • 4,044
  • 30
  • 100
  • 168
user2747607
  • 223
  • 1
  • 2
  • 4

13 Answers13

17

Does the output path exist? BCP does not create the folder before trying to create the file.

Try this before your BCP call:

EXEC xp_cmdshell 'MKDIR "E:\Storage\Export\Data\"'
Daniel Molnar
  • 171
  • 1
  • 4
6

First, rule out an xp_cmdshell issue by doing a simple 'dir c:*.*';

Check out my blog on using BCP to export files.

I had problems on my system in which I could not find the path to BCP.EXE.

Either change the PATH variable of hard code it.

Example below works with Adventure Works.

-- BCP - Export query, pipe delimited format, trusted security, character format
DECLARE @bcp_cmd4 VARCHAR(1000);
DECLARE @exe_path4 VARCHAR(200) = 
    ' cd C:\Program Files\Microsoft SQL Server\100\Tools\Binn\ & ';
SET @bcp_cmd4 =  @exe_path4 + 
    ' BCP.EXE "SELECT FirstName, LastName FROM AdventureWorks2008R2.Sales.vSalesPerson" queryout ' +
    ' "C:\TEST\PEOPLE.TXT" -T -c -q -t0x7c -r\n';
PRINT @bcp_cmd4;
EXEC master..xp_cmdshell @bcp_cmd4;
GO

Before changing the path to \110\ for SQL Server 2012 and the name of the database to [AdventureWorks2012], I received the following error.


enter image description here

After making the changes, the code works fine from SSMS. The service is running under NT AUTHORITY\Local Service. The SQL Server Agent is disabled. The output file was created.

enter image description here

CRAFTY DBA
  • 14,351
  • 4
  • 26
  • 30
  • I modified the code as you suggested by hard coding the path but I get the same error. Unable to open host data file. – user2747607 Sep 04 '13 at 18:59
  • Can you paste a screen shot of the actual error on the post? After the EXEC, can you PRINT @@ERROR to see if there is an error code? – CRAFTY DBA Sep 04 '13 at 19:40
  • Also, can you look at the permissions on the directory and files that you are using? Does the above example work in your environment. – CRAFTY DBA Sep 04 '13 at 19:51
  • Couple more suggestionss: 1 - change the name of the file. using a minus might be an issue. 2 - why is there no delimiters in the output? change "$#Y#$" to "," and the same for "" to see if that is an issue. It is either a permission or command issue. Can not tell w/o having the database on hand. – CRAFTY DBA Sep 04 '13 at 19:58
  • I got it! Since I was specifying the location of BCP.exe I thought I'd try moving the .fmt file to the same location I was executing BCP from "C:\Program Files\Microsoft SQL Server\100\Tools\Binn\" and it worked. Thank you soo much. – user2747607 Sep 04 '13 at 20:40
  • I get this message (so I need to investigate further): Msg 15281, Level 16, State 1, Procedure master..xp_cmdshell, Line 1 [Batch Start Line 0] SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online. – Allan F Mar 19 '20 at 01:34
  • I found some info here: https://www.daktronics.com/support/kb/Pages/DD3360274.aspx i.e. right click server name in SSMS and choose Facets .. The choose Facet value of Surface Area Configuration and see the XPCmdShellEnabled property. – Allan F Mar 19 '20 at 02:00
5

Please check, the file might be opened in another application or program. If it is the case, bcp.exe cannot overwrite the existing file contents.

Rajesh
  • 1,911
  • 1
  • 22
  • 19
  • Creating a unique name for the output file indeed solved it. The testfile c:\csv\export20150415.csv already exists, and removing the old test file / changing a new filename solved it. – Langeleppel Apr 15 '15 at 08:21
5

In my case, I solved The problem in the following way:

my command was :

bcp "select Top 1000 * from abc.dbo.abcd" queryout FileNameWithDirectory -c -t "|" -r "0x0a" -S 192.111.1.111 -U xx -P xxxxx

My FileNameWithDirectory was too long. like "D:\project-abc\R&D\abc-608\FilesNeeded\FilesNeeded\DataFiles\abc.csv".

I change into a simpler directory like : "D:\abc.csv"

Problem solved.

So I guess the problem occurred due to file name exceeding. thus the file was not found.

2

If it works from the command line but not from the SQL Agent, I think it is an authentication issue.

The SQL Server Agent is running under a account. Make sure that the account has the ability to read the format file and generate the output file.

Also, make sure the account has the ability to execute the xp_cmdshell stored procedure.

Write back with your progress ...

CRAFTY DBA
  • 14,351
  • 4
  • 26
  • 30
  • I may have spoken too soon, I tried again from CMD and I got the same error. I verified that I Local System had rights to the output file but I wasn't able to find the format file anywhere. Once I re-created the format file it worked fine from CMD but still not from SQL. The Agent was running as local system but I also tried using the account I'm logged on as and I get the same result. I also tried to execute in a SP but got the same error. – user2747607 Sep 04 '13 at 19:21
  • I got it! Since I was specifying the location of BCP.exe I thought I'd try moving the .fmt file to the same location I was executing BCP from "C:\Program Files\Microsoft SQL Server\100\Tools\Binn\" and it worked. Thank you soo much. – user2747607 Sep 04 '13 at 20:43
2

I received this after I shared my output folder, even when there were no files open.

I created a new, unshared folder for output and all was fine. (might help someone ;-))

Catherine
  • 163
  • 6
1

In my case this fix was simply running in administrator mode.

Arthur Swails
  • 169
  • 14
1

This error can be due to insufficient write permissions to the target folder.

This is a common issue, since the user writing the query might have access to a folder, but the SQL Server Agent or logged-in server account which actually invokes bcp.exe may not.

Geoff Griswald
  • 937
  • 12
  • 24
1

Destination path has to already exist (except for file name).

0

Remove no_output from your command, if you use one offcourse

SET @sql = 'BCP ....'

EXEC master..xp_cmdshell @sql , no_output

EXEC master..xp_cmdshell @sql
Stefan Michev
  • 4,795
  • 3
  • 35
  • 30
0

In case anyone else runs into the same problem: I had ...lesPerson" queryout' rather than ...lesPerson" queryout '

Patrick Schomburg
  • 2,494
  • 1
  • 18
  • 46
0

If your code is writing the data file, and then reading it with BCP, make sure that you CLOSE THE DATA FILE before trying to read it!

Failure to do so gives: 'Unable to open host data-file'.

Python example:

# Management of temporary bulk insert file.

def openBulkInsertFile(self) :
    self.bulkInsertFile = open('c:/tmp/bulkInsertContent.txt', 'w', newline='')
    self.csvWriter = csv.writer(self.bulkInsertFile)

def closeBulkInsertFile(self) :
    self.bulkInsertFile.close()
CodeCabbie
  • 3,098
  • 2
  • 19
  • 30
0

When using a Job in SQL the user that uses the SQL express server is the current user logged, you should give write permission to that user in the folder where the Batch writes the output.

This happens usually only with bcp, when using type commands the ownership goes to the computer(Administrator) and the command runs with out problem.

So if you have a long command in your job just look for the bcp parts.

enter image description here

Alejandro
  • 82
  • 3
  • 12