I thought I would write a few blogs this week for once. I learned something new the other day at work and I thought I would share it with everyone. The other day I had to somehow import a bunch of pdfs from a web server into our new sql server database. After doing some googling and getting my knowledge up on command shell within T-Sql I found it was pretty simple. Below are the steps I did to make it happen!
I ran into a few issues with the pdf being on the web server so to make it easier I copied the file from the server to the sql server on a share for a temp location until the file was imported into the database.
Step 1. Let's set up our temp tables just let the rest of my blog entries.
--remove temp tableIF EXISTS(SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#myfiles'))DROP TABLE #myfiles
IF EXISTS(SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#BinaryFile') ) DROP TABLE #BinaryFile
--Create temp tableCREATE TABLE #myfiles (MyID INT IDENTITY(1,1) PRIMARY KEY, FileName VARCHAR(2000))CREATE TABLE #BinaryFile(FileID UNIQUEIDENTIFIER,filename VARCHAR(50),Team VARCHAR(50),BinaryFile VARBINARY(MAX))
Step 2. Let's get a directory Listing of all the files in the share. With the use of command shell we can easily do this.
INSERT INTO #myfiles (FileName )EXECUTE MASTER.dbo.xp_cmdshell 'DIR "\\yourserver\share" /A-D /B'Step 3. Let's create some variables. These will help in the cursor I wrote to grab the data.
DECLARE @FileName VARCHAR(50) --the pdf name variableDECLARE @Team VARCHAR(20) --the team nameDECLARE @FilePath VARCHAR(200) --file path location for pdf on web serverDECLARE @SqlPath VARCHAR(200) --file path location for pdf on sql serverDECLARE @FileShare VARCHAR(200) --share path for pdf on webserverDECLARE @SqlShare VARCHAR(200) --share path for pdf sql serverDECLARE @SqlCopyOutput INT --to see if the file success copied to sql server
DECLARE @string VARCHAR(1000) --String for dynamic sql command
SET @FileShare = '\\server\share\'
SET @SqlShare ='\\server\share\'
Step 4. The Cursor. I wrote a cursor that will loop through all the files. It will first move them from the web server to the sql server share. After that it will insert them into the database. If it was a successful insert it will then remove them from the sql server share. I had to use a few different commands such as command shell, t-sql, dynamic sql, and open row set. Here is the entire cursor. It is pretty straight forward. As you can see I keep with my baseball theme. I am going to insert the Milwaukee Brewers and Minnesota Twins baseball schedule for 2013.
DECLARE Pdf_Cursor CURSOR FOR
SELECT Pdf.Team,Pdf.FileNameFROM( SELECT FileName ,
SUBSTRING(FileName,6,((( CHARINDEX('2013.', filename) ) +(LEN(FileName)-18)) )) AS Team
FROM #myfiles
WHERE FileName LIKE '2013%'
) PdfOPEN pdf_Cursor FETCH NEXT FROM pdf_cursor INTO @Team, @FileNameWHILE @@FETCH_STATUS = 0
BEGIN
SET @FilePath = @FileShare + @FileName
SET @SqlPath = @SqlShare + @FileName
--Move file from webserver to sql server so it will insert into di_media.
SET @TransferFileString = 'copy ' +@FilePath+ ' ' + @SqlPath
EXEC MASTER..xp_cmdshell @TransferFileString
--making sure the file copied over to the sql serve before inserting into di_media
EXEC MASTER..xp_Fileexist @SqlPath ,@SqlCopyOutput OUTPUT
IF @SqlCopyOutput != 1
SELECT 'Fail to move to share', @FileName
ELSE
BEGIN
SET @string = ' INSERT INTO #BinaryFile( FileID,FILENAME,Team,BinaryFile)'
SET @string = @string + 'SELECT NEWID(),' + CHAR(39) +@FileName + CHAR(39) +',' + CHAR(39) + @Team + CHAR(39) +',BulkColumn FROM Openrowset(Bulk ' + CHAR(39) + @SqlPath + CHAR(39) +', SINGLE_BLOB) AS blob'
EXEC(@string)
--checking to see if pdf made it in the db before deleting from sql server.
IF EXISTS(SELECT * FROM #BinaryFile WHERE filename = @FileName)
BEGIN
SET @string = 'Del ' + @SqlPath
EXEC xp_cmdshell @string
SET @string = ''
END
ELSE
SELECT 'Failed to insert into db', @Team
END
--clearing out path
SET @FilePath = ''
SET @SqlPath = ''
SET @TransferFileString = ''
FETCH NEXT FROM pdf_Cursor INTO @Team, @FileName
END
CLOSE pdf_CursorDEALLOCATE pdf_cursor
Step 5. To query the table. Looks quickly the temp table to insure the data did make it. As we can see it was a success!
SELECT * FROM #BinaryFile
The last thing I want to talk about the open row set I used to insert the actually pdf into the database. This is the key part to the entire thing. Here is the entire command printed out with out using dynamic sql.
INSERT INTO #BinaryFile( FileID,FILENAME,Team,BinaryFile)SELECT NEWID(),'2013.BrewersSchedule.pdf','Brewers',BulkColumn FROM OPENROWSET(BULK '\\serever\share\2013.BrewersSchedule.pdf', SINGLE_BLOB) AS blob
I just learned how to turn this scripting logic into an SSIS package. Later in another blog entry I will show how you can do this using SSIS. It might be more useful in the SSIS package.