如何在不使用本地或者临时文件的情况下将存储过程输出直接写到FTP上的文件?

时间:2020-03-05 18:41:40  来源:igfitidea点击:

我想获取存储过程的结果,并将它们放入CSV文件中的FTP位置。

不过要注意的是,我无法创建本地/临时文件,然后可以通过FTP进行传输。

我采用的方法是使用SSIS包创建一个临时文件,然后在包中包含一个FTP任务以通过FTP将该文件传输过来,但是我们的DBA不允许在任何服务器上创建临时文件。

回复Yaakov Ellis

我认为我们需要说服DBA,让我至少在服务器上使用他们无法运行的共享,或者询问他们如何做。

回复凯夫

我喜欢CLR集成的想法,但是我不认为我们的DBA甚至不知道这是什么,他们也可能不允许这样做。但是我可以在可以计划的SSIS包中的脚本任务中执行此操作。

解决方案

回答

尝试使用CLR存储过程。我们也许可以提出一些建议,但是如果没有先创建一个临时文件,可能仍然很困难。我们可以在另一台计算机上设置共享并写入共享,然后从那里进行ftp吗?

回答

在可用于创建临时文件的任何地方都可以使用服务器吗?如果是这样,请制作一个Web服务,该服务返回一个包含文件内容的数组。从计算机上调用Web服务,我们可以在其中创建一个临时文件,使用数组的内容来构建临时文件并通过ftp对其进行ftp。

如果根本没有地方可以创建临时文件,那么我将看不到如何通过FTP发送任何内容。

回答

如果允许我们实现CLR集成程序集,则实际上可以使用FTP,而不必编写临时文件:

public static void DoQueryAndUploadFile(string uri, string username, string password, string filename)
{
    FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(uri + "/" + filename);
    ftp.Method = WebRequestMethods.Ftp.UploadFile;
    ftp.Credentials = new System.Net.NetworkCredential(username, password);

    using(StreamWriter sw = new StreamWriter(ftp.GetRequestStream()))
    {
        // Do the query here then write to the ftp stream by iterating DataReader or other resultset, following code is just to demo concept:
        for (int i = 0; i < 100; i++)
        {
            sw.WriteLine("{0},row-{1},data-{2}", i, i, i);
        }
        sw.Flush();
    }
}

回答

来自FTP服务器的脚本,只需调用存储的proc。

回答

The catch though is that I cannot create 
  a local/temporary file that I can then FTP over.

此限制没有任何意义,请尝试与DBA进行友好交流并向他/她解释。任何Windows进程或者作业在适当的位置(即%TEMP%文件夹)中创建临时文件都是完全合理的。实际上,SSIS运行时本身经常在其中创建临时文件,因此,如果DBA允许我们运行SSIS,则他允许我们创建临时文件:)。

只要DBA理解这些临时文件不会给他带来问题或者其他工作量(说明他不必设置特殊权限或者对其进行备份等),他就应该同意让我们创建它们。

DBA的唯一维护任务是定期清除%TEMP%目录,以防SSIS作业失败并留下文件。但是无论如何,他还是应该这样做,因为许多其他过程也可能这样做。一个简单的SQL Agent作业就可以做到这一点。