views:

185

answers:

3

I am developing a win32 windows application with Delphi and MS SQL Server. it works fine in LAN but I am trying to add the support for SQL Server remote connections (= working with a DB that can be accessed with an external IP, as described in this article: http://support.microsoft.com/default.aspx?scid=kb;EN-US;914277).

Basically I have a Table in DB where I keep the DocumentID, the document description and the Document path (like \\FILESERVER\MyApplicationDocuments\45.zip).

Of course \\FILESERVER is a local (LAN) path for the server but not for the client (as I am now trying to add the support for remote connections).

So I need a way to access \\FILESERVER even if of course I cannot see it in LAN.

I found the following T-SQL code snippet that is perfect for the "download trick":

SELECT BulkColumn as MyFile FROM OPENROWSET(BULK '\FILESERVER\MyApplicationDocuments\45.zip' , SINGLE_BLOB) AS X

With the code above I can download a file on the client.

But how to upload it? I need an "Uppload trick" to be able to insert new files, but also to delete or replace existing files.

Can anyone suggest? If a trick is not available could you suggest an alternative? Like an extended stored procedure or calling some .net assembly from the server.

A: 

In ideal world I would create simple: - ASP.NET Web Service - or .Net Remoting Service (faster than web service) - or new .Net 4.0 RIA service.

Deploy it to the SQL Server on custom TCP/IP port

This service would listen to the port and client would request the file via the service. The service would get the file via local LAN and communicate with the DB via local OLE DB connection.

I would not use any SQl Server "web service" support - this is security and performance issues.

UPDATE: Since this is Delphi app - you can do the same using Delphi, even though above solution still valid, but more work to integrate different technologies. Delphi has its own tools to build remote applications

IMHO
I agree about security and performance issues. But what I am tring to do is also to avoid complex deployment. If I have to install webserver to all my customers deploment becomes harder, moreover even if I delegate document management to a webservice I need anyway to use SQL server for "remoting data". I cannot change my applcation, it would be so much work that rewriting from scratch makes more sense (or no sense at all, since rewriting from scratch means choosing a different technology like ASP.NET and not Delphi).
Common sense suggest you have to do something special, since you are trying to gain access to protected resource - LAN. You can write the whole thiing in Delphi without need to have a web server - this can be done via windows service and TCP/IP listener which is very easy to do in Delphi.If you still want to find a trick - see above solution, posted by Chris - FILESTREAM or store data in BLOB's.
IMHO
+1  A: 

If you have sql 2008, then you can use FILESTREAM, then sql server will automatically throw it out to disk.

If you have sql 2005, I'd consider just moving the data into a varbinary(max) column and deal with it that way (also pretty simple).

If neither of those apply OR you can't shove it into a varbinary column, then I would not use sql server to handle the actual file contents and instead just have a web service which stored the file on the file system or a SAN that the web service can easily access. (same as IMHO)

UPDATE: One other idea that crossed my mind. If you are using SQL 2005/08 then you can write a CLR Stored procedure in .Net. This could handle transferring the blob data to / from the local file system.

Chris Lively
I support SQL 2005/08, so a CLR Stored procedure is a viable option (filestream isn't and varbinary(max) column etiher because typically customers use Express edition and have 50+ GB of documents, that doesn't fit well into the 4GB DB size). Anyway even if I go for a trick (as IMHO correctly discourages me to do) or for the CLR sp I have a load on SQL Server memory right? So if I have to transfer 10 100MB files in parallel all the server (1GB) memory will be used. CLR advantage is for improving security only compared to "trick". Am i Right?
After considering also security issues I decided to go for the CLR stored procedure, it impacts less my code, I just need to change the routines that read/write files from shared folder and replace them with calls to the CLR stored procedures.
A: 

If you are on 2005, you could try to store file in temp blob field of some temp table, and then call stored procedure which should put the file where you want it, and update path field as you want it.

In that stored procedure you must use extended stored procedures (xp_something), which allow access to file system. That means that those should be enabled for sql server.

BTW You are trying to use relational DB as Document database. That will, sooner or later, backfire.

dmajkic
By using xp_cmdshell I am able to move the data from a temp blob field to a network path. This I could say suffices my requirement.I am not persisting the document in the db forever, and I am also using an extended stored procedure to copy the temp blob to a shared network folder.I agree there is a "backfire" risk, because if document traffic becomes significantly > Relational DB traffic I can have a problem. But once I'll feel the fire I can design another solution. I can set as sqlserver process owner a user that can just read/write one network folder. Comments?