views:

426

answers:

3

I ask this question as a followup of this question.

A solution that uses bcp and xp_cmdshell, that is not my desired solution, has been posted here.

I am new to c# (since I am a Delphi developer) anyway I was able to create a simple CLR stored procedure by following a tutorial.

My task is to move a file from the client file system to the server file system (the server can be accessed using remote IP, so I cannot use a shared folder as destination, this is why I need a CLR stored procedure).

So I plan to:

  1. store from Delphi the file in a varbinary(max) column of a temporary table
  2. call the CLR stored procedure to create a file at the desired path using the data contained in the varbinary(max) field

Imagine I need to move C:\MyFile.pdf to Z:\MyFile.pdf, where C: is a harddrive on local system and Z: is an harddrive on the server. C is in New York, Z is in London and there is no VPN between them, just https connection.

I provide the code below (not working) that someone can modify to make it work? Here I suppose to have a table called MyTable with two fields: ID (int) and DATA (varbinary(max)). Please note it doesn't make a difference if the table is a real temporary table or just a table where I temporarly store the data. I would appreciate if some exception handling code is there (so that I can manage an "impossible to save file" exception).

I would like to be able to write a new file or overwrite the file if already existing.

[Microsoft.SqlServer.Server.SqlProcedure]
public static void VarbinaryToFile(int TableId)
{
   using (SqlConnection connection = new SqlConnection("context connection=true"))
   {
      connection.Open();
      SqlCommand command = new SqlCommand("select data from mytable where ID = @TableId", connection);
      command.Parameters.AddWithValue("@TableId", TableId);
      // This was the sample code I found to run a query
      //SqlContext.Pipe.ExecuteAndSend(command);
      // instead I need something like this (THIS IS META_SYNTAX!!!):
      SqlContext.Pipe.ResultAsStream.SaveToFile('z:\MyFile.pdf');
   }
}

(one subquestion is: is this approach correct or there is a way to directly pass the data to the CLR stored procedure so I don't need to use a temp table?)

If the subquestion's answer is No, could you describe the approach of avoiding a temp table? So is there a better way then the one I describe above (=temp table + Stored procedure)? A way to directly pass the dataastream from the client application to the CLR stored procedure? (my files can be any size but also very big)

A: 

See http://www.mssqltips.com/tip.asp?tip=1662

unclepaul84
Thanks for the link, but this cannot work for me, it can be good for text files, but I need to store any file, also a 100MB file, and the approach at the article it is not for those cases.
One thing come into my mind overnight: is it possible to use the approach described in the article also for very large files? I mean by using the example in the link would it be possible to do something like: exec ns_lib.dbo.ns_txt_file_write @file_name ='c:\temp\test_file.txt' , @file_contents=0x4D5A90000300000004000.... (this long list are the file content)?Of course by changing to varbinary(max) the second parameter.Is there a limit to the amount of data that can be passed in this way?If this is true it means that my subquestions's answer is YES.
A: 

Why are you putting these files into database? If you have http/https connection you can upload the file to the server, write into a protected dierctory and create a page to list those files and give a link to download it. If you want to store some extra information you can write it into database. You just need to change the name of file at server side (use a unique name).

Manjoor
A: 

After some research I conclude that it makes no sense, it is better to drop the support of 2005 and use 2008 fielstream feature. I can have a conditional logic to choose between 2005 and 2008 and use filestream only for 2005.