Success!
我在名为的数据库上创建了一个存储过程sp_UploadFileToSFTP,它使用 PSFTP.EXE 发送文件。
-- ================================================================================================================================
-- Description: Upload File to SFTP
-- - Creates "SFTPUploadScript.bat" and "SFTPUploadScript.txt" scripting files to control psftp.exe, then executes the batch file
-- - Requires a local @ScriptFolder on the SQL Server to create files inside, and which contains psftp.exe
-- - "SFTPUploadScript.bat" needs to be run once manually from the SQL Server desktop to capture the keypair of the SFTP site
-- After this, the script will work automatically
-- ================================================================================================================================
CREATE PROCEDURE sp_UploadFileToSFTP
@FilePathToUpload varchar(1000),
@SFTPSiteAddress varchar(1000),
@SFTPLogin varchar(1000),
@SFTPPassword varchar(1000),
@SFTPRemoteFolder varchar(1000)
AS
BEGIN
SET NOCOUNT ON;
--Declare Variables
DECLARE @ScriptFolder varchar(1000)
SET @ScriptFolder = 'C:\SFTPBatchFiles\'
DECLARE @CommandString AS varchar(8000)
--Delete Existing files if they exist
SET @CommandString = 'del "'+ @ScriptFolder + 'SFTPUploadScript.txt"'
EXEC master..xp_cmdshell @CommandString
SET @CommandString = 'del "'+ @ScriptFolder + 'SFTPUploadScript.bat"'
EXEC master..xp_cmdshell @CommandString
--Create Batch fle with login credentials
SET @CommandString = 'echo "'+ @ScriptFolder +'psftp.exe" ' + @SFTPSiteAddress + ' -l ' + @SFTPLogin + ' -pw ' + @SFTPPassword + ' -b "' + @ScriptFolder + 'SFTPUploadScript.txt" > "' + @ScriptFolder + 'SFTPUploadScript.bat"'
EXEC master..xp_cmdshell @CommandString
--Create SFTP upload script file
SET @CommandString = 'echo cd "' + @SFTPRemoteFolder + '" > "' + @ScriptFolder + 'SFTPUploadScript.txt"'
EXEC master..xp_cmdshell @CommandString
SET @CommandString = 'echo put "' + @FilePathToUpload + '" >> "' + @ScriptFolder + 'SFTPUploadScript.txt"'
EXEC master..xp_cmdshell @CommandString
--Run the Batch File
SET @CommandString = @ScriptFolder + 'SFTPUploadScript.bat'
EXEC master..xp_cmdshell @CommandString
END
GO
然后我可以从另一个存储过程中调用它,如下所示:
sp_UploadFileToSFTP 'C:\FileToUpload\Test.txt','sftp.mysite.com','[email protected] /cdn-cgi/l/email-protection','Password1234','UploadFolder/In here/'
一切都很完美,运行大约需要四分之一秒,这是一个非常简洁和稳定的解决方案。
与我之前使用 SQL Server 将文件放入文件夹中,然后使用 Visual Basic SFTP 上传脚本每 15 分钟检查该文件夹中是否有新文件相比,这要好得多:)
如果您想自己尝试一下,您只需要在 SQL Server 的 C:\ 驱动器上建立一个名为“SFTPBatchFiles”的文件夹,然后在其中放置 psftp.exe,它是 PuTTY 的一部分。
您还需要一个信任的服务器管理员,他将允许您使用 xp_cmdshell 运行 psftp 命令和您自己的批处理文件,并且他们可能需要在您的防火墙中打开一条路由,以便您可以直接从 SQL Server 连接到远程站点。
最后,您还需要能够通过远程桌面访问 SQL Server,因为您需要运行一次手动创建的批处理文件,并在 psftp 要求您接受新密钥对时按“Y”。之后,一切就一帆风顺了。
没有 SSIS,没有 WINSCP,没有 Visual Studio,没有数小时的崩溃和调试!
现在唯一的问题是,如果 FTP 传输由于某种原因失败,存储过程仍然报告成功,我不会将 psftp 错误消息带回 SQL Server。
我的下一个任务是捕获从 xp_cmdshell 生成的状态和错误消息,并向用户提供一些详细的反馈,并在进程失败时生成错误。
UPDATE:
捕获来自远程 FTP 站点的错误和反馈
--Run the Batch File
DROP TABLE IF EXISTS #CommandOutput
CREATE TABLE #CommandOutput (ReadLine varchar(1000))
SET @CommandString = @ScriptFolder + 'SFTPUploadScript.bat'
INSERT #CommandOutput
EXEC master..xp_cmdshell @CommandString
--Check for Invalid Password error
IF EXISTS (SELECT ReadLine
FROM #CommandOutput
WHERE ReadLine LIKE '%Invalid Password%')
BEGIN
PRINT 'Invalid Password Error!'
END
现在,批处理文件运行时,批处理文件的所有输出(如果手动运行,通常会显示在屏幕上)将逐行插入到名为 #CommandOutput 的临时表中。
批处理文件运行后,您可以查询 #CommandOutput 以查看传输发生了什么。
我在输出中的任何位置添加了对“无效密码”一词的简单检查,因为这是您可能遇到的常见错误。您可以根据需要添加任意数量的这些检查,也可以将整个表导入到每次作业运行时发送给您的电子邮件中,将表记录到 FTP 事件日志表中,或者进行任意数量的其他操作。