Below is the procedure I am trying to write:
First I need to generate a file in the SQL Server 1 with some data that can be queried from the same server
Then I need to move the file to a FTP server from SQL Server 1, from there I need to fetch the details of the file from SQL Server 2.
How can I do with the help of the bcp
utility?
Create a file in sql server with queried data
DECLARE @FileName varchar(1000),@bcpCommand varchar(1000),
@FileGeneratePath varchar(100)
DECLARE @exe_path4 VARCHAR(200) = ' cd C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn & ';
Set @FileGeneratePath = '\\192.168.XX.XXX\Files\'
Set @FileName = REPLACE('SampleFile'+ CONVERT(varchar(10),GETDATE(),100)+'.xls',' ','') --'\\192.168.29.111\Files\authors'+ Convert(varchar(40),Getdate(),121) + '.csv'
SET @bcpCommand = @exe_path4 +' bcp.exe "SELECT top 10 * from [192.168.XX.XXX].DATABASE.dbo.FamilyAccountDetails where Convert(varchar(10),LastUpdatedon,100) > Convert(varchar(10),Getdate()-30,100)" queryout "'
SET @bcpCommand = @bcpCommand + @FileGeneratePath + @FileName + '" -c -t"|" -Uusername -Ppassword -S192.168.XX.XXX'
EXEC master..xp_cmdshell @bcpCommand, no_output
exe_path4 is the path of bcp exe. For more details of bcp utility check this. and also this
xp_cmdshell is an extended stored procedure and it allows you to execute an operating system command via a SQL Statement. Extended stored procedures are programs written in langauges like C++ that are then attached to an instance of SQL Server. Once attached, they can be referenced just like a regular stored procedure.
no_output
in the xp_cmdshell act like set nocount on
.
Stored procedure to move a file from sql server to an ftp
In the below store procedures , i created a text file to execute in command prompt to move file to the ftp and vice versa. Both files generated in the SQL Server temp folder, not in the local temp. you can also give a particular folder for the file generation.
/*
Exec spPullFileToFTP
@FTPServer = '192.168.YY.YYY' ,
@FTPUser = 'username' ,
@FTPPWD = 'password' ,
@SourcePath = '\\192.168.YY.YYY\Files\' ,
@SourceFiles = 'SampleFileJan16201.xls' ,
@DestPath = 'FileToCopy/New/'
*/
Create Procedure spPullFileToFTP
@FTPServer varchar(128),
@FTPUser varchar(128),
@FTPPwd varchar(128),
@SourcePath varchar(128),
@SourceFiles varchar(128),
@DestPath varchar(128),
@FTPMode varchar(10)=''
as
Set Nocount On
SET @FTPMode = 'binary' -- ascii, binary or blank for default.
DECLARE @cmd varchar(1000)
DECLARE @workfile varchar(128)
DECLARE @nowstr varchar(25)
-- Get the %TEMP% environment variable.
DECLARE @tempdir varchar(128)
CREATE TABLE #tempvartable(info VARCHAR(1000))
INSERT #tempvartable EXEC master..xp_cmdshell 'echo %temp%'
SET @tempdir = (SELECT top 1 info FROM #tempvartable)
IF RIGHT(@tempdir, 1) <> '\' SET @tempdir = @tempdir + '\'
DROP TABLE #tempvartable
-- Generate @workfile
SET @nowstr = replace(replace(convert(varchar(30), GETDATE(), 121), ' ', '_'), ':', '-')
SET @workfile = 'FTP_SPID' + convert(varchar(128), @@spid) + '_' + @nowstr + '.txt'
-- Deal with special chars for echo commands.
select @FTPServer = replace(replace(replace(@FTPServer, '|', '^|'),'<','^<'),'>','^>')
select @FTPUser = replace(replace(replace(@FTPUser, '|', '^|'),'<','^<'),'>','^>')
select @FTPPwd = replace(replace(replace(@FTPPwd, '|', '^|'),'<','^<'),'>','^>')
select @DestPath = replace(replace(replace(@DestPath, '|', '^|'),'<','^<'),'>','^>')
IF RIGHT(@SourcePath, 1) <> '\' SET @SourcePath = @SourcePath + '\'
-- Build the FTP script file.
select @cmd = 'echo ' + 'open ' + @FTPServer + ' > ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + @FTPUser + '>> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + @FTPPwd + '>> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + 'prompt ' + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
IF LEN(@FTPMode) > 0
BEGIN
select @cmd = 'echo ' + @FTPMode + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
END
IF LEN(@DestPath) > 0
BEGIN
select @cmd = 'echo ' + 'cd ' + @DestPath + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
END
select @cmd = 'echo ' + 'mput ' + @SourcePath + @SourceFiles + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
print @cmd
select @cmd = 'echo ' + 'quit' + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
-- Execute the FTP command via script file.
select @cmd = 'ftp -s:' + @tempdir + @workfile
create table #a (id int identity(1,1), s varchar(1000))
insert #a
EXEC master..xp_cmdshell @cmd
select id, ouputtmp = s from #a
-- Clean up.
drop table #a
select @cmd = 'del ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
go
**Output File **
open 192.168.YY.YYY
Username
Password
prompt
binary
cd FileToCopy/AdvisoryPortal/
mput \\192.168.YY.YYY\Files\SampleFileJan16201.xls
quit
Stored Procedure to move a file from ftp to SQL Server
/*
exec spPullFileFromFTP
@FTPServer = '192.168.YY.YYY' ,
@FTPUser = '11111' ,
@FTPPWD = 'FtpPassword' ,
@SourcePath = '/FileToCopy/Sample/' ,
@SourceFiles = 'SampleFileJan12201.xls' ,
@DestPath = '\\192.168.XX.XXX\Files\New\'
*/
Create procedure spPullFileFromFTP
@FTPServer varchar(128),
@FTPUser varchar(128),
@FTPPwd varchar(128),
@SourcePath varchar(128),
@SourceFiles varchar(128),
@DestPath varchar(128),
@FTPMode varchar(10)=''
as
Begin
SET @FTPMode = 'binary' -- ascii, binary or blank for default.
DECLARE @cmd varchar(1000)
DECLARE @workfile varchar(128)
DECLARE @nowstr varchar(25)
-- Get the %TEMP% environment variable.
DECLARE @tempdir varchar(128)
CREATE TABLE #tempvartable(info VARCHAR(1000))
INSERT #tempvartable EXEC master..xp_cmdshell 'echo %temp%'
SET @tempdir = (SELECT top 1 info FROM #tempvartable)
IF RIGHT(@tempdir, 1) <> '\' SET @tempdir = @tempdir + '\'
DROP TABLE #tempvartable
-- Generate @workfile
SET @nowstr = replace(replace(convert(varchar(30), GETDATE(), 121), ' ', '_'), ':', '-')
SET @workfile = 'FTP_SPID' + convert(varchar(128), @@spid) + '_' + @nowstr + '.txt'
-- Deal with special chars for echo commands.
select @FTPServer = replace(replace(replace(@FTPServer, '|', '^|'),'<','^<'),'>','^>')
select @FTPUser = replace(replace(replace(@FTPUser, '|', '^|'),'<','^<'),'>','^>')
select @FTPPwd = replace(replace(replace(@FTPPwd, '|', '^|'),'<','^<'),'>','^>')
select @SourcePath = replace(replace(replace(@SourcePath, '|', '^|'),'<','^<'),'>','^>')
IF RIGHT(@DestPath, 1) = '\' SET @DestPath = LEFT(@DestPath, LEN(@DestPath)-1)
-- Build the FTP script file.
select @cmd = 'echo ' + 'open ' + @FTPServer + ' > ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + @FTPUser + '>> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + @FTPPwd + '>> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + 'prompt ' + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
IF LEN(@FTPMode) > 0
BEGIN
select @cmd = 'echo ' + @FTPMode + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
END
select @cmd = 'echo ' + 'lcd ' + @DestPath + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
IF LEN(@SourcePath) > 0
BEGIN
select @cmd = 'echo ' + 'cd ' + @SourcePath + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
END
select @cmd = 'echo ' + 'mget ' + @SourceFiles + ' >> ' + @tempdir + @workfile
--select @cmd = 'echo ' + 'mget ' + @SourcePath + @SourceFiles + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
select @cmd = 'echo ' + 'quit' + ' >> ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
-- Execute the FTP command via script file.
select @cmd = 'ftp -s:' + @tempdir + @workfile
create table #a (id int identity(1,1), s varchar(1000))
insert #a
EXEC master..xp_cmdshell @cmd
select id, ouputtmp = s from #a
-- Clean up.
drop table #a
select @cmd = 'del ' + @tempdir + @workfile
EXEC master..xp_cmdshell @cmd
End
**Output File **
open 192.168.YY.YYY
Username
Password
prompt
binary
lcd \\192.168.XX.XXX\Files\New
cd /FileToCopy/AdvisoryPortal/
mget SampleFileJan12201.xls
quit
If any doubts in the commands, please check this.
To bulk copy from file to Database table
Declare @SQL varchar(500)
set @SQL = 'BULK INSERT BGL_CRM_FamilyAccountDetails FROM '+''''+'//192.168.YY.XXX/Files/New/'+ @FileName +''''+
' WITH (DATAFILETYPE =' +''''+'char' +''''+', FIELDTERMINATOR = '+''''+'|'+''''+', ROWTERMINATOR = '+''''+'\n'+''''+')'
EXEC(@SQL)