Tuesday, March 27, 2012

Reading and Writing Files using T-SQL ( Sql Server )

Reading a File:

OPENROWSET is a T-SQL function that allows reading data from many sources including using the SQL Server’s BULK import capability. One of the useful features of the BULK provider is its ability to read individual files from the file system into SQL Server, such as loading a data from a text file or a Word document into a SQL Server table.

The BULK option was added to T-SQL in SQL Server 2005 and it persists in SQL Server 2008.
When used with the BULK provider keyword you can name a data file to read as one of three types of objects:
  1. SINGLE_BLOB, which reads a file as varbinary(max)
  2. SINGLE_CLOB, which reads a file as varchar(max) 
  3. SINGLE_NCLOB, which reads a file as nvarchar(max) 
OPENROWSET returns a single column, named BulkColumn, as its result. Here’s an example that reads a text file:
Query:
SELECT BulkColumn 
FROM OPENROWSET (BULK 'C:\Test\test.txt', SINGLE_CLOB) MyFile
Output:

Writing a File:

1) Write a File using  xp_cmdshell:
Before using xp_cmdshell, we first have to enable xp_cmdshell feature, due to security reasons it is disabled by default.
See the following post
Steps to enable OLE Automation and xp_cmdshell procedures in sql server 2005 and 2008
                                                                     OR
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  
Query:
Declare @text varchar(max)
Declare @data cursor
Declare @a varchar(20)
Declare @b varchar(30)
DECLARE @cmd sysname, @var sysname

SET @data = Cursor for
Select FirstName,LastName from dbo.Employees // Northwind database


Open @data
WHILE (1 <> 0)
BEGIN

    FETCH NEXT FROM @data INTO @a , @b

    SET @text ='First Name :'+@a+' and Last Name :'+@b

    IF ( @@FETCH_STATUS <>  0 )
    BEGIN
        BREAK;
    END

SET @cmd = 'echo ' + @text + ' >> c:\var_out.txt'
exec master..xp_cmdshell @cmd

END
In the above code, we declare a cursor  @data in which we stored first name and last name of employees and then open the @data cursor and place an infinite while loop. The IF condition is placed inside the while loop to check @@Fetch_Status. The loop will continue works until the @@Fetch_Status does not return 0.
In the end the records are written to the var_out.txt file. There are multiple records in the employees table, all of them are appended in the same file.

2) Using OLE Automation Stored Procedures:
CREATE PROCEDURE sp_OAToFile(@FileName varchar(255), @Text1 text) AS
DECLARE @FS int, @OLEResult int, @FileID int

EXECUTE @OLEResult = sp_OACreate 'Scripting.FileSystemObject', @FS OUT
IF @OLEResult <> 0 PRINT 'Scripting.FileSystemObject'

--Open a file
execute @OLEResult = sp_OAMethod @FS, 'OpenTextFile', @FileID OUT, @FileName, 8, 1
IF @OLEResult <> 0 PRINT 'OpenTextFile'

--Write Text1
execute @OLEResult = sp_OAMethod @FileID, 'WriteLine', Null, @Text1
IF @OLEResult <> 0 PRINT 'WriteLine'

EXECUTE @OLEResult = sp_OADestroy @FileID
EXECUTE @OLEResult = sp_OADestroy @FS

GO

SET QUOTED_IDENTIFIER OFF
GO 
SET ANSI_NULLS ON
GO
In the above code, we created a stored procedure which takes two parameters file name and text. File name is the name of the file which will be created and text is the content which is written to the file.
sp_OACreate creates an instance of OLE object.
sp_OAMethod calls the method of OLE object.
and last one sp_OADestroy procedure destroys the OLE object.

References:
OLE Automation Stored Procedures.
http://msdn.microsoft.com/en-us/library/ms190501(v=sql.110).aspx
Read file reference
http://www.mssqltips.com/sqlservertip/1643/using-openrowset-to-read-large-files-into-sql-server/

1 comment: