Using FTP in Transact-SQL

Using FTP in Transact-SQL
GuestAuthor on 10/1/2001 in Stored Procs
mfemenel sent us a great article on how you can FTP a file using T-SQL. He writes "The following article is based on a resource I found at 15Seconds.com but will be helpful here for all you SQL Developers. The article assumes a bit of existing VB knowledge, I’ll attempt to make this one useful for “everyman(woman)”. I’ve included the compiled DLL file, so if you don’t want to mess around with VB, there’s no need to, you can skip straight to registering the DLL on your server.

Introduction

I’ve seen a few posts asking “How do I ftp a file into SQL” Well, if you have 6.5 or 7.0 this article should be helpful. Unfortunately it’s not an easy answer, but it’ll work great once you’ve set it up. The answer is that there isn’t a function in SQL to let you do this, you need to create a DLL to help you. For those of you who just hit the floor, get up, dust yourself off, take a deep breath and keep going. It’s not that bad, I promise.

Download the suppport files

There are a few files for you to download which go along with this article. (Note: All the files are in this ZIP file.) The first one, FTP_SQLDLL.cls is the VB file we’ll use to create our FTP_SQLTEAM.dll. Our second one is SQLTeam_FTP.sql which is what we’ll use in Query Analyzer to execute our compiled DLL. Also included in the zip file is the DLL itself (FTP_SQLTEAM.dll), all compiled and ready to go, should you not feel like building it yourself. I’ve also added a Word document called “API Notes” which contains a little more detail about the VB side of creating the DLL that didn’t fit into a SQL Server article.

The DLL

The fine folks at Microsoft have a DLL called “WinInet”. It provides you with internet functionality. We’re going to make some API calls to that DLL and take advantage of their code. Let’s think about this for a second. Using this method, you will be able to make API calls from TSQL!

To register the DLL, follow these steps. Copy the FTP_SQLTEAM.dll to your server. I prefer to keep my DLL files in Winnt/System folder. Now, from a command line, type in Regsvr32.exe /DLLNAME.dll to register the dll.

The Transact-SQL Script

From Query Analyzer or a text editor go ahead and open up the SQLTeam_FTP.sql file so we can go through the details:

In the first section, we’re not doing anything new, just setting up some variables to catch the various things that we need in our script:

--Create an instance of FTP Object
Set NoCount on
DECLARE @hr int			--Holds error value for each sp_OA function
DECLARE @oPKG int		--Holds the handle of the object
Declare @source varchar(255)	--Hold error info
Declare @description varchar(255)--Hold error description
Declare @connected  int		--Hold the handle of the Internet session
declare @opened int		--Hold the handle of the connection to the FTP Server
declare @getfile bit		--Result of the success(1)/Failure(2) of the getfile operation

Our next block of code is creating an instance of the object. We’re going to store the object token, which is just an integer identifying the created object in the variable @oPKG. We’ll use it everytime we run a method or property setting, so the functions know which object (were we to have more than one) we’re talking about. Let’s go through this line by line.

Here, we’re going to tell SQL to create an instance of the FTP object we created (using sp_OACreate) and store it’s “object id” in a variable called @oPkg.

--First, we want to create the object and store it's handle in @oPKG
EXEC @hr = 	sp_OACreate 'FTP_SQLTeam.FTP_SQLDll', @oPKG OUT

Our value @hr will catch the return code of the sp_OACreate method. If the return code is 0 then we were successful in creating an instance of our object. Any other return value is a failure. I find it extremely useful, at least on our initial script set up, to put in a print line so we know which block is giving us our errors.

--Check for errors
IF @hr <> 0
BEGIN
    PRINT 	'***  Create Package object failed'
    EXEC  	sp_OAGetErrorInfo @oPKG, @source OUT, @description OUT
		select @description ,@source
    RETURN
END

Now that we have an instance of our object created, we can start putting it to work by invoking those Public Methods we created for it in our DLL. If you’re used to coding in VB I’ve put in a reference to what the VB syntax would be. Let’s look at that first line as we’ll use it a few more times for each of our subsequent functions.

We’re going to execute a method of our object (Open_Internet). First, we pass it the object id from when we created the object(@oPkg), then pass the method name “Open_Internet”, then a variable to catch any return parameter from the method call. If there is no return value, you can just use “null”, then we specify the parameters the function expects. Here is a big caveat. The parameters are not like parameters you use in TSQL. Query Analyzer does not see @alias as a sql variable. You must use the same name as your original function declaration expects.

--Establish our internet connection
-- VB Equivalent=Open_Internet("myftp", 1, vbNullString, vbNullString, 0)
	Exec @hr=sp_OAMethod @oPkg,Open_Internet,@opened Out,
			@alias='myftp',
			@accesstype=1,
			@proxy="",
			@bypass="",
			@flags=0

The next step is to connect to an FTP site. In this case we'll connect to ftp.microsoft.com.

--Connect to the FTP Server(microsoft.com)
--vb Equivalent Connect_Internet(connected, "ftp.microsoft.com", , __
--		"anonymous", "graz@sqlteam.com", 1, 0, 0)
	Exec @hr=sp_OAMethod @oPkg,Connect_Internet,@Connected Out,
		@handleid=@opened,
		@server='ftp.microsoft.com',
		@port=0,
		@username='anonymous',
		@pwd='graz@sqlteam.com',
		@service=1,
		@flags=0,
		@context=0

And finally we can copy a file from their ftp server to the hard drive of the local machine.

--Get the file and direct it to our local drive
--vb Equivalent Get_File(sessionid, remotefile, newfile, _
--		failifexists, flagsandattr, flags, context) As Boolean
	Exec @hr=sp_OAMethod @oPkg,Get_File,@getfile OUT,
		@sessionid=@Connected,
		@remotefile='/bussys/readme.txt',
		@newfile='c:/msreadme.txt',
		@failifexists=0,
		@flagsandattr=0,
		@flags=1,
		@context=0
Conclusion

That should do it! Remember, I’ve kept this pretty simple so it was easy to follow. You can make it a much more robust script by adding parameters for the file name, the server, userid, pwd, etc. The article on 15seconds.com points out several other function calls you can make that I didn’t go into. Here’s another link that details what functions are available in WinInet.dll. Get your feet wet with this version first. Then you can add in the fancier stuff. Walk before you run!

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 在ASP.NET开发中,定时任务是一种常见功能,用于在固定时间间隔内执行特定操作,比如数据同步、清理缓存或发送通知等。以下是实现ASP.NET定时任务的详细步骤和关键要点: ASP.NET定时任务通常通过System.Threading.Timer或System.Timers.Timer实现,二者都能周期性触发事件。在ASP.NET中,可以利用后台线程或HttpApplication生命周期事件来启动定时器。 System.Threading.Timer:适合在独立线程上运行任务,避免阻塞主线程,适合轻量级任务。 System.Timers.Timer:在多线程环境下,它会自动管理线程,更适合服务器端复杂任务。 创建定时器对象,设置Interval属性为10000毫秒(10秒),并注册Elapsed事件。该事件会在每个时间间隔结束时触发。 在Elapsed事件中编写要执行的代码,确保代码执行效率高,避免阻塞,因为长时间运行的任务可能影响其他请求。 通过Timer.Start()启动定时器,Timer.Stop()停止定时器。在ASP.NET中,可以在Application_Start和Application_End事件中控制定时器的启动和停止,确保服务器启动时定时器开始运行,关闭时停止。 在多用户环境下,如果定时任务会修改共享状态,必须考虑线程安全问题,可以使用锁或其他同步机制来确保数据一致性。 将应用程序部署到IIS时,需设置应用程序池的回收策略,避免定时任务因应用程序回收而中断。同时,确保IIS配置支持长时间运行的请求。 为定时任务添加日志记录非常重要,可以帮助排查问题并监控任务执行情况。 定时任务过于频繁可能会影响服务器性能,进而影响其他请求的响应时间。可根据需求调整时间间隔,或
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值