February 15, 2008 at 2:32 pm
Hi Experts,
I have to find the latest file in a folder and export data to a table in sql server.
The code should be something that has to be incorporated into a t-sql stored procedure.
The file name would for example abc_defYYYYMMDD.xls.
would i be able to find the latest file in the folder using the the datestamp (YYYYMMDD) in the filename.
Please note i would have files in other format and names with datestamp attached to it, so the code has to pick specific file for which the file name starts with 'abc_def'
and export data to a table.
Any help would be highly appreciated
Alicia Rose
February 15, 2008 at 6:26 pm
Hi Alicia...
Since you're trying to "export" the file from an .xls file to a table, you'll need to follow a couple of "rules" about the format of the .xls file. Take a look at the following URL to see a couple of methods for doing this to of "Import" to an SQL Server table...
http://www.simple-talk.com/sql/t-sql-programming/sql-server-excel-workbench/
Finding the latest file is actually a cake walk, especially the way you've named the files... if course, you'd replace the 'C:\Temp' with the proper UNC or path.
CREATE TABLE #MyFiles (Name SYSNAME, Depth TINYINT, IsFile TINYINT)
INSERT INTO #MyFiles
EXEC Master.dbo.xp_DirTree 'C:\Temp',1,1
SELECT TOP 1 Name
FROM #MyFiles
WHERE Name LIKE 'abc_def[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].xls'
AND ISDATE(SUBSTRING(Name,8,8))=1
ORDER BY Name Desc
There's a couple of other ways to do this same thing including a trip to a Cmd window, using a LinkedServer in the text mode, or writing a custom CLR (one of the only things I recommend writing a CLR for).
--Jeff Moden
Change is inevitable... Change for the better is not.
February 18, 2008 at 2:36 am
Excel files are like any other files in that they have datestamps. You can red these directly into SQL Server so as to be sure to pick up the latest Excel file. See some example code that uses the FileSystem Object (FSO),
http://www.simple-talk.com/content/article.aspx?article=374#forum
Best wishes,
Phil Factor
February 18, 2008 at 11:34 am
Although using FSO through sp_OA is a wonderful idea... it still requires "SA" privs. Not complaining or arguing... just reminding
--Jeff Moden
Change is inevitable... Change for the better is not.
February 18, 2008 at 11:49 am
Jeff,
I seem to be plugging Robyn Page Articles today (I helped with these). This tells you how to do the process with sa, without letting it anywhere normal users, or causing any security concerns.
http://www.simple-talk.com/sql/t-sql-programming/process-delegation-workbench/
You'd only need to use this sort of technique where using sa became a problem. It works fine, but you will get up to a 20 second delay. Still, 20 secs for Alicia's excel file aint bad.
I must admit, once we've got this sort of mechanism set up for a database system, we put all the 'back-office' stuff in it. It is dead handy. Works with 2000 as well! We've used it with several websites.
Best wishes,
Phil Factor
February 18, 2008 at 12:02 pm
Good stuff, Phil... we had some critical stuff we needed to do as a batch job and, for sure, it required "SA" privs and xp_cmdShell...
I love my DBA... she said, "Jeff, if you can write it, I can run it". So, I built this wonderful import system that would dutifully import files and move them to a "completed" directory after successful import and provide all sorts of good information... of course, it used xp_cmdShell and MOVE/DELETE commands and all sorts of high security risk things.
She bottled it up in a job, set the user to run it as as "SA", and gave the night operators privs to execute the job. They can't see it run so it sends them an email to say "Running" and another to say "Job completed... here's the results".
I asked her how she did it and she said "Proxy User". How very simple...
Like you said, it's not instant, but it works just fine for batch jobs.
--Jeff Moden
Change is inevitable... Change for the better is not.
February 18, 2008 at 12:15 pm
LOL!
I think I love your DBA as well. Don't get to thinking they're all like that. Try and persuade her to write for SSC or ST!
Process-delegation solves all sorts of problems. Inherently Slow processes, processes that require a history, Processes that need to happen on an event, rather than user input. Processes that require god-like privileges.
Best wishes,
Phil Factor
February 19, 2008 at 6:54 am
While we're on the topic of processes involving SA and xp_cmdshell, a quick, down and dirty way to load the contents of a directory (date ordered) is to use DIR /B /D. For example, to load your excel files...
exec master..xp_cmdshell 'DIR *.xls /B /D'
Just my .02
DAB
February 19, 2008 at 10:28 am
Try this... no "SA" privs required...
EXEC Master.dbo.xp_Dirtree 'C:\',1,1
... can be loaded into a table and filtered for use with something like BULK INSERT. Only advantage over what Doug posted is it does not require any special privs.
--Jeff Moden
Change is inevitable... Change for the better is not.
February 19, 2008 at 11:04 pm
Hi,
We have an another way if you can use DTS.
Through ActiveXScript we can use FSO and find out the latest file from the folder and assign the valid excel file name into the Microsoft Excel Connection object.
It is easy if you are using FSO in Active Script and assigning the file to your Microsoft Connection Object.
February 20, 2008 at 2:17 am
I tried through linkedserver. Plz check it out .... :w00t:
SELECT
*
FROM
sys.sysservers
ORDER BY srvid DESC
EXEC master.dbo.sp_addlinkedserver
@server = N'ExcelSte12'
,@srvproduct=N'Excel'
,@provider=N'Microsoft.Jet.OLEDB.4.0'
,@datasrc=N'C:\Book1.xls'
,@provstr=N'Excel 8.0'
SELECT
*
FROM
ExcelSte12...[Sheet1$]
In this "Sheet1$" is the name of the ExcelSheet.
---
February 20, 2008 at 2:19 am
Drifting slightly off-topic here, but what about a TSQL routine that uses the xp_cmdShell 'DIR' trick to get an XML list of the files, with their full paths, including the subdirectories. I find this one very useful myself. I haven't added the bit that picks up the date of the file because this is specific to your international settings in Windows, and I've never thought of a foolproof way of doing it.
[font="Courier New"]SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spGetFilePaths]
@BaseDirectory VARCHAR(255),-- the initial directory e.g. 'c:\mypath'
@filespec VARCHAR(10) = '*.*',--the files you want
@wanted VARCHAR(10) = 'files',--files or directories
@subdirectories INT = 1,--do we want the subdirectories too
@xmlFileList XML OUTPUT-- we are essentially passing back a table
/*
e.g.
DECLARE @FileList XML
EXECUTE spGetFilePaths 'S:\work\programs\SQL\Templates\ssc', '*.sql',
@subdirectories = 1, @XMLFileList = @FileList OUTPUT
SELECT @filelist
*/
AS
SET NOCOUNT ON
DECLARE @DirectoryName VARCHAR(255)
DECLARE @Directory_ID INT
DECLARE @command VARCHAR(255)
DECLARE @directory TABLE
(
Directory_ID INT IDENTITY(1, 1),
directory VARCHAR(255),
done INT
)
DECLARE @line TABLE ( line VARCHAR(255) )
DECLARE @files TABLE
(
files_ID INT IDENTITY(1, 1),
thepath VARCHAR(255),
[Filename] VARCHAR(100),
[Path] VARCHAR(255)
)
INSERT INTO @directory ( directory, done )
SELECT @baseDirectory,
0
WHILE 1 = 1 --forever until a break!
BEGIN
DELETE FROM @line --clear out the work table
SELECT TOP 1
@Directory_ID = directory_ID,
@DirectoryName = directory
FROM @directory
WHERE done = 0
IF @@rOWCOUNT = 0 --if nothing there left to do
BREAK ;
SELECT @command = 'dir "' + @directoryname + '\' + @Filespec
+ '"'--build the DIR command
INSERT INTO @line--pop it into our work table
EXECUTE xp_cmdshell @command
IF NOT EXISTS ( SELECT line
FROM @line
WHERE line LIKE 'File Not Found' )
INSERT INTO @files--and into our file table
(
thePath,
[filename],
[path]
)
SELECT @directoryname + '\' + SUBSTRING(line, 40, 255),
SUBSTRING(line, 40, 255),
@DirectoryName
FROM @line
WHERE SUBSTRING(line, 25, 8) = ''
AND LEFT(line, 1) <> ' '
IF @Filespec NOT IN ( '*.*', '*.' )
BEGIN--get the directories
DELETE FROM @line
SELECT @command = 'dir "' + @directoryname + '"'
INSERT INTO @line
EXECUTE xp_cmdshell @command
END
INSERT INTO @directory ( directory, done )--and store them
--so we can process them in a later loop.
SELECT @directoryname + '\' + SUBSTRING(line, 40, 255),
0
FROM @line
WHERE SUBSTRING(line, 25, 8) = '<dir>'
AND SUBSTRING(line, 40, 255) NOT IN ( '..', '.' )
UPDATE @directory
SET done = -1
WHERE directory_ID = @directory_ID
IF @subdirectories = 0
BREAK
END
IF @wanted = 'files' --have we asked for the files
SET @xmlFileList = ( SELECT thePath,
[filename],
[path]
FROM @files
FOR
XML PATH('thefile'),
ROOT('thefiles'),
TYPE
)
ELSE --or just the directory structure
SET @xmlFileList = ( SELECT thepath = directory
FROM @directory
FOR
XML PATH('thefile'),
ROOT('thefiles'),
TYPE
)
[/font]
(prettified by the prettifier on http://extras.sqlservercentral.com/prettifier/prettifier.aspx)
Best wishes,
Phil Factor
Viewing 12 posts - 1 through 12 (of 12 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy