Insert SQL Server records via ftp file.txt

3

I have the following structure in a .txt file from an FTP server:

CodigoPedido: 120952

DataPedido: 2014-03-11-10:19

LocalVenda: MERCADO LIVRE

Status: A ENVIAR

Parceiro: 0

IdCliente: 103002

NomeCliente: Juliano Ramires Garcia | JRAMIRES GARCIA

Is there any way to automate the process for SQL Server to connect to FTP, load the file, do a parse, insert the registry and delete the FTP file?

    
asked by anonymous 11.03.2014 / 15:11

1 answer

3

Initial recommendation

First of all, I would recommend creating a separate process to do this.

It could be a script in ShellScript, Python, PHP or a similar language executed in a scheduled way by cron (Linux) or Task Scheduler (Windows).

This script would be responsible for retrieving the file, reading the data, validating and then sending a command to SQL, being this passive in this story.

Solution with T-SQL

Enable running system commands

However, the T-SQL language ( Transact-SQL ) has commands that allow interaction with the environment.

The first step is to enable the xp_cmdshell command. To do this, follow the steps in official documentation :

-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO

Calling FTP

Then, in your SQL script, you can recover the remote file by invoking the ftp utility of Windows. The -s parameter allows you to specify a file with the FTP commands. See this example :

Set @cmd = 'ftp -s:"C:\comandos.txt" 127.0.0.0'
exec master..xp_cmdshell @cmd

In the above example, the comandos.txt file would have the FTP commands to be executed.

But the important thing here is that with the possibility of running any program, you can virtually do whatever you want. You can call a program in Java or any script.

Reading the file into a variable

Then, to read the file, you can use the OPENROWSET command. You have an example in the documentation link that allows you to read the file in binary format. By modifying the format for characters, you can put in any variable. Use SINGLE_CLOB if the contents of the file are encoded in ASCII or SINGLE_NCLOB if it is Unicode. Example:

DECLARE @conteudo NVARCHAR(2000)
SELECT @conteudo = BulkColumn
FROM OPENROWSET(BULK N'C:\dados.txt', SINGLE_CLOB) AS Document;

Making the "parse"

The last step would be to do parse . In fact, the ideal is to already save the file in an appropriate format, separated by commas, with quotation marks, and so on. Try not to leave this load for SQL Server because it was not meant for this.

I will not develop the solution because it would be very specific and not worth it. However, I'll leave some commands that can help if you need to.

There are several string manipulation functions :

  • With CHARINDEX and PATINDEX you can find the position of labels .

  • So, with SUBSTRING you can get the text that is in front of them. It's not that complicated, it's more a matter of manual labor.

  • Final considerations

    Although this solution is possible, there are better and more flexible ways, as presented at the beginning of the answer.

    Safety

    As for the security issue, this can be a problem depending on where FTP is. If it is an internal server of the company with access only by the administrators this would not be so bad. However, if it is an external FTP it can be a big flaw. First, FTP is not a secure protocol, data travels in plain text, for example. Second, you would be adding another invasion point. If a hacker compromises the FTP server, it can inject spurious commands into the text file and be able to execute some command on its database server. What would be the name of a client, can be a SQL Injection.

    Performance

    Another factor that can be impacted is the performance of your database server. Depending on how many files are read on the day, the fact that SQL has to connect to FTP (which may be a slow connection) and then interpret the content, can generate an unnecessary additional load on the server.

    I do not know how SQL Server treats the threads and processes, but one of them would be blocked waiting for the response of the ftp command, for example.

        
    11.03.2014 / 16:43