Hey guys,
Goodnight!
Remember the post I made about Enabling OLE Automation via T-SQL on SQL Server where did I say that I would post about some cool functions exemplifying the use of OLE Automation in SQL Server? So, that's the post 🙂
To avoid putting too many Stored Procedures and Functions here in the post and making it too long, I created a compressed file with the source code of the scripts which are available here and I will just explain the use of each of them.
fncFile_Exists_FSOUsage: SELECT CLR.dbo.fncArquivo_Exist_FSO(‘C:\Teste.txt’)
Source code:
CREATE FUNCTION [dbo].[fncArquivo_Existe_FSO] (@strArquivo VARCHAR(1000))
RETURNS INT
AS
BEGIN
DECLARE
@hr INT,
@objFileSystem INT,
@retorno INT,
@source VARCHAR(250),
@description VARCHAR(2000)
EXEC @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
RETURN 0
END
EXEC @hr = sp_OAMethod
@objFileSystem,
'FileExists',
@retorno OUT,
@strArquivo
IF (@hr <> 0)
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
EXEC sp_OADestroy
@objFileSystem
RETURN 0
END
EXEC sp_OADestroy
@objFileSystem
RETURN @retorno
END
Usage: SELECT CLR.dbo.fncDiretorio_Existe_FSO(‘C:\Dirceu’)
Source code:
CREATE FUNCTION [dbo].[fncDiretorio_Existe_FSO] (@strDiretorio VARCHAR(1000))
RETURNS INT
AS
BEGIN
DECLARE
@hr INT,
@objFileSystem INT,
@retorno INT,
@source VARCHAR(250),
@description VARCHAR(2000)
EXEC @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
RETURN 0
END
EXEC @hr = sp_OAMethod
@objFileSystem,
'FolderExists',
@retorno OUT,
@strDiretorio
IF (@hr <> 0)
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
EXEC sp_OADestroy
@objFileSystem
RETURN 0
END
EXEC sp_OADestroy
@objFileSystem
RETURN @retorno
END
Usage: SELECT * FROM CLR.dbo.fncLer_Arquivo_FSO(‘C:\Teste.txt’)
Source code:
CREATE FUNCTION [dbo].[fncLer_Arquivo_FSO] (@Ds_Arquivo VARCHAR(256))
RETURNS @Tabela_Final TABLE (Ds_Linha VARCHAR(8000))
AS
BEGIN
DECLARE @OLEResult INT
DECLARE @FileSystemObject INT
DECLARE @FileID INT
DECLARE @Message VARCHAR (8000)
DECLARE @Tabela TABLE ( Ds_Linha varchar(8000) )
EXECUTE @OLEResult = sp_OACreate 'Scripting.FileSystemObject', @FileSystemObject OUT
IF @OLEResult <> 0
BEGIN
SET @Message = 'Scripting.FileSystemObject - Error code: ' + CONVERT (VARCHAR, @OLEResult)
INSERT INTO @Tabela_Final SELECT @Message
RETURN
END
EXEC @OLEResult = sp_OAMethod @FileSystemObject, 'OpenTextFile', @FileID OUT, @Ds_Arquivo, 1, 1
IF @OLEResult <> 0
BEGIN
SET @Message = 'OpenTextFile - Error code: ' + CONVERT (VARCHAR, @OLEResult)
INSERT INTO @Tabela_Final SELECT @Message
RETURN
END
EXECUTE @OLEResult = sp_OAMethod @FileID, 'ReadLine', @Message OUT
WHILE (@OLEResult >= 0)
BEGIN
INSERT INTO @Tabela(Ds_Linha) VALUES( @Message )
EXECUTE @OLEResult = sp_OAMethod @FileID, 'ReadLine', @Message OUT
END
EXECUTE @OLEResult = sp_OADestroy @FileID
EXECUTE @OLEResult = sp_OADestroy @FileSystemObject
INSERT INTO @Tabela_Final
SELECT Ds_Linha FROM @Tabela
RETURN
END
Usage: EXEC CLR.dbo.stpDelete_Arquivo_FSO ‘C:\Teste.txt’
Source code:
CREATE PROCEDURE [dbo].[stpApaga_Arquivo_FSO] (@strArquivo VARCHAR(1000))
AS
BEGIN
DECLARE
@hr INT,
@objFileSystem INT,
@source VARCHAR(250),
@description VARCHAR(2000)
EXEC @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
END
IF (CLR.dbo.fncArquivo_Existe(@strArquivo) = 1)
BEGIN
EXEC @hr = sp_OAMethod
@objFileSystem,
'DeleteFile',
NULL,
@strArquivo
END
IF (@hr <> 0)
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
EXEC sp_OADestroy
@objFileSystem
END
EXEC sp_OADestroy
@objFileSystem
END
Usage: EXEC CLR.dbo.stpCopia_Arquivo_FSO ‘C:\Teste.txt’, ‘C:\Arquivos\Novo_Arquivo.log’, 1 — Will overwrite if it already exists (3rd parameter)
Source code:
CREATE PROCEDURE [dbo].[stpCopia_Arquivo_FSO] (
@strOrigem VARCHAR(MAX),
@strDestino VARCHAR(MAX),
@sobrescrever INT = 0
)
AS
BEGIN
IF (dbo.fncArquivo_Existe(@strOrigem) = 1 AND @strOrigem != @strDestino)
BEGIN
DECLARE
@hr INT,
@objFileSystem INT,
@source VARCHAR(250),
@description VARCHAR(2000)
EXEC @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
RAISERROR('Object Creation Failed 0x%x, %s, %s',16,1,@hr,@source,@description)
RETURN
END
IF (dbo.fncArquivo_Existe(@strDestino) = 1)
IF (@sobrescrever = 1)
EXEC dbo.stpApaga_Arquivo_FSO @strDestino
ELSE
BEGIN
PRINT 'O arquivo de destino já existe e o parâmetro sobrescrever foi definido como NÃO'
RETURN
END
EXEC @hr = sp_OAMethod
@objFileSystem,
'CopyFile',
NULL,
@strOrigem,
@strDestino
IF (@hr <> 0)
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
EXEC sp_OADestroy
@objFileSystem
RAISERROR('Method Failed 0x%x, %s, %s',16, 1, @hr, @source, @description)
PRINT @source
PRINT @description
RETURN
END
EXEC sp_OADestroy
@objFileSystem
END
ELSE
PRINT 'O arquivo de origem não existe ou é igual ao arquivo de destino'
END
GO
Usage: EXEC CLR.dbo.stpWrite_Arquivo_FSO(‘C:\Teste.txt’, ‘File Write Test’)
Source code:
CREATE PROCEDURE [dbo].[stpEscreve_Arquivo_FSO] (
@String VARCHAR(MAX),
@Ds_Arquivo VARCHAR(1501)
)
AS
BEGIN
DECLARE
@objFileSystem INT,
@objTextStream INT,
@objErrorObject INT,
@strErrorMessage VARCHAR(1000),
@Command VARCHAR(1000),
@hr INT
SET NOCOUNT ON
SELECT
@strErrorMessage = 'opening the File System Object'
EXECUTE @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @HR = 0
SELECT
@objErrorObject = @objFileSystem,
@strErrorMessage = 'Creating file "' + @Ds_Arquivo + '"'
IF @HR = 0
EXECUTE @hr = sp_OAMethod
@objFileSystem,
'CreateTextFile',
@objTextStream OUT,
@Ds_Arquivo,
2,
True
IF @HR = 0
SELECT
@objErrorObject = @objTextStream,
@strErrorMessage = 'writing to the file "' + @Ds_Arquivo + '"'
IF @HR = 0
EXECUTE @hr = sp_OAMethod
@objTextStream,
'Write',
NULL,
@String
IF @HR = 0
SELECT
@objErrorObject = @objTextStream,
@strErrorMessage = 'closing the file "' + @Ds_Arquivo + '"'
IF @HR = 0
EXECUTE @hr = sp_OAMethod
@objTextStream,
'Close'
IF @hr <> 0
BEGIN
DECLARE
@Source VARCHAR(255),
@Description VARCHAR(255),
@Helpfile VARCHAR(255),
@HelpID INT
EXECUTE sp_OAGetErrorInfo
@objErrorObject,
@source OUTPUT,
@Description OUTPUT,
@Helpfile OUTPUT,
@HelpID OUTPUT
SELECT
@strErrorMessage = 'Error whilst ' + COALESCE(@strErrorMessage, 'doing something') + ', ' + COALESCE(@Description, '')
RAISERROR (@strErrorMessage,16,1)
END
EXECUTE sp_OADestroy
@objTextStream
EXECUTE sp_OADestroy
@objTextStream
END
Usage: EXEC dbo.stpWrite_File_V2_FSO(‘C:\Teste.txt’, ‘File Write Test’)
Source code:
CREATE PROCEDURE [dbo].[stpEscreve_Arquivo_V2_FSO] (
@String VARCHAR(MAX),
@Ds_Arquivo VARCHAR(1501)
)
AS
BEGIN
SET NOCOUNT ON
DECLARE
@objFileSystem INT,
@objTextStream INT,
@objFolderExists INT,
@objErrorObject INT,
@strErrorMessage VARCHAR(1000),
@Folder VARCHAR(500) = REVERSE(RIGHT(REVERSE(@Ds_Arquivo), (LEN(@Ds_Arquivo) - CHARINDEX('\', REVERSE(@Ds_Arquivo), 1)) + 1)),
@hr INT
SELECT
@strErrorMessage = 'opening the File System Object'
EXECUTE @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr = 0
SELECT
@objErrorObject = @objFileSystem,
@strErrorMessage = 'Checking if the directory "' + @Folder + '" exists'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objFileSystem,
'FolderExists',
@objFolderExists OUT,
@Folder
-- Folder does not exists. Need to create it
IF (@objFolderExists = 0)
BEGIN
IF @hr = 0
SELECT
@objErrorObject = @objFileSystem,
@strErrorMessage = 'Creating folder "' + @Folder + '"'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objFileSystem,
'CreateFolder',
@objFolderExists OUT,
@Folder
END
IF @hr = 0
SELECT
@objErrorObject = @objFileSystem,
@strErrorMessage = 'Creating file "' + @Ds_Arquivo + '"'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objFileSystem,
'CreateTextFile',
@objTextStream OUT,
@Ds_Arquivo,
2,
True
IF @hr = 0
SELECT
@objErrorObject = @objTextStream,
@strErrorMessage = 'writing to the file "' + @Ds_Arquivo + '"'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objTextStream,
'Write',
NULL,
@String
IF @hr = 0
SELECT
@objErrorObject = @objTextStream,
@strErrorMessage = 'closing the file "' + @Ds_Arquivo + '"'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objTextStream,
'Close'
EXECUTE sp_OADestroy
@objFileSystem
IF @hr <> 0
BEGIN
DECLARE
@Source VARCHAR(255),
@Description VARCHAR(255),
@Helpfile VARCHAR(255),
@HelpID INT
EXECUTE sp_OAGetErrorInfo
@objErrorObject,
@Source OUTPUT,
@Description OUTPUT,
@Helpfile OUTPUT,
@HelpID OUTPUT
SELECT
@strErrorMessage = 'Error whilst ' + COALESCE(@strErrorMessage, 'doing something') + ', ' + COALESCE(@Description, '')
RAISERROR (@strErrorMessage,16,1)
END
END
Usage: EXEC dbo.stpCria_Diretorio_FSO(‘C:\Dirceu’)
Source code:
CREATE PROCEDURE [dbo].[stpCria_Diretorio_FSO] (
@Folder VARCHAR(500)
)
AS
BEGIN
DECLARE
@objFileSystem INT,
@objFolderExists INT,
@objErrorObject INT,
@strErrorMessage VARCHAR(1000),
@hr INT
SET NOCOUNT ON
SELECT
@strErrorMessage = 'opening the File System Object'
EXECUTE @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr = 0
SELECT
@objErrorObject = @objFileSystem,
@strErrorMessage = 'Checking if the folder "' + @Folder + '" exists'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objFileSystem,
'FolderExists',
@objFolderExists OUT,
@Folder
IF (@objFolderExists = 0)
BEGIN
IF @hr = 0
SELECT
@objErrorObject = @objFileSystem,
@strErrorMessage = 'Creating folder "' + @Folder + '"'
IF @hr = 0
EXECUTE @hr = sp_OAMethod
@objFileSystem,
'CreateFolder',
@objFolderExists OUT,
@Folder
END
EXECUTE sp_OADestroy
@objFileSystem
EXECUTE sp_OADestroy
@objFolderExists
IF @hr <> 0
BEGIN
DECLARE
@Source VARCHAR(255),
@Description VARCHAR(255),
@Helpfile VARCHAR(255),
@HelpID INT
EXECUTE sp_OAGetErrorInfo
@objErrorObject,
@Source OUTPUT,
@Description OUTPUT,
@Helpfile OUTPUT,
@HelpID OUTPUT
SELECT
@strErrorMessage = 'Error whilst ' + COALESCE(@strErrorMessage, 'doing something') + ', ' + COALESCE(@Description, '')
EXECUTE sp_OADestroy
@objErrorObject
RAISERROR (@strErrorMessage,16, 1)
END
END
Usage: EXEC CLR.dbo.stpInformacoes_Arquivo_FSO(‘C:\Teste.txt’)
Source code:
CREATE PROCEDURE [dbo].stpInformacoes_Arquivo_FSO(@strArquivo VARCHAR(255))
AS
BEGIN
DECLARE
@hr INT,
@objFileSystem INT,
@objFile INT,
@ErrorObject INT,
@ErrorMessage VARCHAR(255),
@Path VARCHAR(255),--
@ShortPath VARCHAR(255),
@Type VARCHAR(100),
@DateCreated DATETIME,
@DateLastAccessed DATETIME,
@DateLastModified DATETIME,
@Attributes INT,
@size INT
SET nocount ON
SELECT
@hr = 0,
@ErrorMessage = 'opening the file system object '
EXEC @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr = 0
SELECT
@ErrorMessage = 'accessing the file ''' + @strArquivo + '''',
@ErrorObject = @objFileSystem
IF @hr = 0
EXEC @hr = sp_OAMethod
@objFileSystem,
'GetFile',
@objFile OUT,
@strArquivo
IF @hr = 0
SELECT
@ErrorMessage = 'getting the attributes of ''' + @strArquivo + '''',
@ErrorObject = @objFile
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'Path',
@Path OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'ShortPath',
@ShortPath OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'Type',
@Type OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'DateCreated',
@DateCreated OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'DateLastAccessed',
@DateLastAccessed OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'DateLastModified',
@DateLastModified OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'Attributes',
@Attributes OUT
IF @hr = 0
EXEC @hr = sp_OAGetProperty
@objFile,
'size',
@size OUT
IF @hr <> 0
BEGIN
DECLARE
@Source VARCHAR(255),
@Description VARCHAR(255),
@Helpfile VARCHAR(255),
@HelpID INT
EXECUTE sp_OAGetErrorInfo
@ErrorObject,
@Source OUTPUT,
@Description OUTPUT,
@Helpfile OUTPUT,
@HelpID OUTPUT
SELECT
@ErrorMessage = 'Error whilst ' + @ErrorMessage + ', ' + @Description
RAISERROR (@ErrorMessage,16,1)
END
EXEC sp_OADestroy
@objFileSystem
EXEC sp_OADestroy
@objFile
SELECT
[Path] = @Path,
[ShortPath] = @ShortPath,
[Type] = @Type,
[DateCreated] = @DateCreated,
[DateLastAccessed] = @DateLastAccessed,
[DateLastModified] = @DateLastModified,
[Attributes] = @Attributes,
[Size] = @size
RETURN @hr
END
Usage: EXEC CLR.dbo.stpMove_Arquivo_FSO ‘C:\Teste.txt’, ‘C:\Arquivos\Novo_Arquivo.log’, 1 — Will overwrite if it already exists (3rd parameter)
Source code:
CREATE PROCEDURE [dbo].[stpMove_Arquivo_FSO] (
@strOrigem VARCHAR(MAX),
@strDestino VARCHAR(MAX),
@sobrescrever INT = 0
)
AS
BEGIN
IF (dbo.fncArquivo_Existe(@strOrigem) = 1 AND @strOrigem != @strDestino)
BEGIN
DECLARE
@hr INT,
@objFileSystem INT,
@source VARCHAR(250),
@description VARCHAR(2000)
EXEC @hr = sp_OACreate
'Scripting.FileSystemObject',
@objFileSystem OUT
IF @hr <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
RAISERROR('Object Creation Failed 0x%x, %s, %s',16,1,@hr,@source,@description)
RETURN
END
IF (dbo.fncArquivo_Existe(@strDestino) = 1)
IF (@sobrescrever = 1)
EXEC dbo.stpApaga_Arquivo_FSO @strDestino
ELSE
BEGIN
PRINT 'O arquivo de destino já existe e o parâmetro sobrescrever foi definido como NÃO'
RETURN
END
EXEC @hr = sp_OAMethod
@objFileSystem,
'CopyFile',
NULL,
@strOrigem,
@strDestino
IF (@hr <> 0)
BEGIN
EXEC sp_OAGetErrorInfo
@objFileSystem,
@source OUT,
@description OUT
EXEC sp_OADestroy
@objFileSystem
RAISERROR('Method Failed 0x%x, %s, %s',16, 1, @hr, @source, @description)
PRINT @source
PRINT @description
RETURN
END
ELSE BEGIN
EXEC dbo.stpApaga_Arquivo_FSO @strOrigem
END
EXEC sp_OADestroy
@objFileSystem
END
ELSE
PRINT 'O arquivo de origem não existe ou é igual ao arquivo de destino'
END
Did you see how easy and simple it is? Now you can play with files without having to worry about creating functions and stored procedures using C# and compiling the CLR database (If you want to use the CLR to manipulate files instead of OLE Automation, WHICH I RECOMMEND, access the post How to list, read, write, copy and move files with the CLR (C#)).
As a bonus, I'm going to give you another stored procedure, which has the function of, using a file path, separating the directory and the file into two distinct variables:
stpFile_Separates_Name_Directory:
USE [CLR]
GO
CREATE PROCEDURE [dbo].[stpArquivo_Separa_Nome_Diretorio] (@strArquivo VARCHAR(1000), @str_DIR VARCHAR(500) OUT, @str_FILE VARCHAR(500) OUT)
AS
BEGIN
SET NOCOUNT ON
SELECT
@str_DIR = REVERSE(RIGHT(REVERSE(@strArquivo), (LEN(@strArquivo) - CHARINDEX('\', REVERSE(@strArquivo), 1)) + 1))
SELECT
@str_FILE = REVERSE(LEFT(REVERSE(@strArquivo), CHARINDEX('\', REVERSE(@strArquivo), 1) - 1))
END
How to use:
DECLARE
@str_DIR VARCHAR(500),
@str_FILE VARCHAR(500)
EXEC CLR.dbo.stpArquivo_Separa_Nome_Diretorio
@strArquivo = '\\servidor\Pasta 1\Diretorio 2\Arquivos\Nome do Arquivo - 20140614.xlsx', -- varchar(1000)
@str_DIR = @str_DIR OUTPUT, -- varchar(500)
@str_FILE = @str_FILE OUTPUT -- varchar(500)
PRINT @str_DIR -- Vai imprimir na tela "\\servidor\Pasta 1\Diretorio 2\Arquivos\"
PRINT @str_FILE -- Vai imprimir na tela "Nome do Arquivo - 20140614.xlsx"
That's all folks!
Until the next post.
Dirceu Resende
Database & BI Architect · Microsoft MVP · MCSE, MCSA, MCT, MTA, MCP.
Comentários (0)
Carregando comentários…