Just for a quick review, xp_dirtree has three parameters:
- directory - This is the directory you pass when you call the stored procedure; for example 'D:\Backup'.
- depth - This tells the stored procedure how many subfolder levels to display. The default of 0 will display all subfolders.
- isfile - This will either display files as well as each folder. The default of 0 will not display any files.
DECLARE
@BasePath varchar(1000)
,@Path varchar(1000)
,@FullPath varchar(2000)
,@Id int;
--This is your
starting point.
SET @BasePath = 'D:\Backup';
--Create a temp
table to hold the results.
IF OBJECT_ID('tempdb..#DirectoryTree')
IS NOT NULL
DROP TABLE
#DirectoryTree;
CREATE TABLE #DirectoryTree (
id int IDENTITY(1,1)
,fullpath varchar(2000)
,subdirectory nvarchar(512)
,depth int
,isfile bit);
--Create a
clustered index to keep everything in order.
ALTER TABLE #DirectoryTree
ADD CONSTRAINT PK_DirectoryTree PRIMARY
KEY CLUSTERED (id);
--Populate the
table using the initial base path.
INSERT
#DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @BasePath,1,1;
UPDATE
#DirectoryTree SET fullpath = @BasePath;
--Loop through
the table as long as there are still folders to process.
WHILE EXISTS (SELECT id FROM #DirectoryTree WHERE
isfile = 0)
BEGIN
--Select the first row that is a folder.
SELECT TOP
(1)
@Id = id
,@FullPath = fullpath
,@Path = @BasePath + '\' + subdirectory
FROM #DirectoryTree WHERE isfile = 0;
IF @FullPath = @Path
BEGIN
--Do this section if the we are
still in the same folder.
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @Path,1,1;
UPDATE #DirectoryTree
SET fullpath = @Path
WHERE fullpath IS NULL;
--Delete the processed folder.
DELETE FROM #DirectoryTree WHERE
id = @Id;
END
ELSE
BEGIN
--Do this section if we need to
jump down into another subfolder.
SET @BasePath = @FullPath;
--Select the first row that is
a folder.
SELECT TOP (1)
@Id = id
,@FullPath = fullpath
,@Path = @BasePath + '\' + subdirectory
FROM #DirectoryTree WHERE isfile = 0;
INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @Path,1,1;
UPDATE #DirectoryTree
SET fullpath = @Path
WHERE fullpath IS NULL;
--Delete the processed folder.
DELETE FROM #DirectoryTree WHERE
id = @Id;
END
END
--Output the
results.
SELECT fullpath + '\' + subdirectory AS 'CompleteFileList'
FROM
#DirectoryTree
ORDER BY fullpath,subdirectory;
--Cleanup.
IF OBJECT_ID('tempdb..#DirectoryTree')
IS NOT NULL
DROP TABLE
#DirectoryTree;
GO
This code will process one folder level at a time since
we're specifying 1 for the depth parameter.
For each folder in the #DirectoryTree table, we get a list of files and
subfolders and insert it to the #DirectoryTree table.
INSERT
#DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree @Path,1,1;
If it's a folder, then it the file parameter will be 0 and
the WHILE loop will process once it gets further down the loop. The folder needs a clustered index to keep
all the rows in order.
ALTER TABLE #DirectoryTree
ADD CONSTRAINT PK_DirectoryTree PRIMARY
KEY CLUSTERED (id);
After each folder is processed, the folder row is deleted
from the table. This is necessary so the
WHILE loop doesn't turn into an infinite loop.
DELETE FROM #DirectoryTree WHERE
id = @Id;
The full path is being saved for output later, so comparing
it to the current base path will let us know if we need to update the @BasePath
parameter.
IF @FullPath = @Path
--Continue processing the same
folder.
ELSE
SET @BasePath = @FullPath;
--Start processing the next subfolder.
This is how we can keep looping through each subfolder until
each one has been processed.
The final step is to output the results.
The final step is to output the results.
SELECT fullpath + '\' + subdirectory AS 'CompleteFileList'
FROM
#DirectoryTree
ORDER BY fullpath,subdirectory;
I have gotten pretty good performance out of this script. Even traversing the C:\Windows folder on my test VM, I can get the report to return all 62000+ files in 14000+ folders within about 6 minutes. Hopefully this example will prove to be helpful for your
everyday tasks. Enjoy!
No comments:
Post a Comment