使用存储过程和批量复制程序 (bcp) 实用程序通过 FTP 将文件从一个 SQL 服务器移动到另一个服务器

Moving files from one SQL Server to another through FTP by using a stored procedure and bulk copy program (bcp) utility

下面是我正在尝试编写的程序:

  1. 首先我需要在 SQL 服务器 1 中生成一个文件,其中包含一些可以从同一服务器查询的数据

  2. 然后我需要将文件从 SQL 服务器 1 移动到 FTP 服务器,从那里我需要从 [=28= 获取文件的详细信息] 服务器 2.

如何使用 bcp 实用程序?

在 sql 服务器中用查询的数据创建一个文件

    DECLARE @FileName varchar(1000),@bcpCommand varchar(1000),
            @FileGeneratePath varchar(100)
    DECLARE @exe_path4 VARCHAR(200) = ' cd C:\Program Files\Microsoft SQL Server\Client SDK\ODBC0\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是bcp exe的路径。 有关 bcp 实用程序的更多详细信息 check this. and also this

xp_cmdshell 是一个扩展存储过程,它允许您通过 SQL 语句执行操作系统命令。扩展存储过程是用 C++ 等语言编写的程序,然后附加到 SQL 服务器的实例。附加后,它们可以像常规存储过程一样被引用。

no_output 在 xp_cmdshell 中表现得像 set nocount on

将文件从 sql 服务器移动到 ftp

的存储过程

在下面的存储过程中,我创建了一个文本文件以在命令提示符下执行以将文件移动到 ftp,反之亦然。这两个文件都在 SQL 服务器临时文件夹中生成,而不是在本地临时文件夹中。您还可以为文件生成指定一个特定的文件夹。

/*     
    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

**输出文件**

open 192.168.YY.YYY 
Username
Password
prompt  
binary 
cd FileToCopy/AdvisoryPortal/ 
mput \192.168.YY.YYY\Files\SampleFileJan16201.xls 
quit 

将文件从 ftp 移动到 SQL 服务器的存储过程

/*     
    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

**输出文件**

open 192.168.YY.YYY
Username
Password
prompt  
binary 
lcd \192.168.XX.XXX\Files\New 
cd /FileToCopy/AdvisoryPortal/ 
mget SampleFileJan12201.xls 
quit 

如果对命令有任何疑问,请check this

bulk copy 从文件到数据库 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)