使用T-SQL生成基于目录的目录和文件列表

时间:2017-03-27 19:03:06

标签: sql-server tsql

我在sql server中有一个存储为路径的大量文件列表。将路径分解为目录很容易,但是,我需要能够一次在一个级别上显示所有文件和文件夹的列表。 SQL Server有一些内置的实用程序来处理服务器本地文件,但在这种情况下它们不适用。

使用通配符将返回当前目录下的所有内容,因此我已将其丢弃。

数据:

C:\test\file.txt
C:\test\level2\file.txt
C:\test\level2\bc.txt
C:\test\level3\another.txt

理想情况下,我想传入一个文件夹,然后查看该级别的所有文件和文件夹。然后我可以在treegrid控件中呈现它,但那部分超出了问题的范围。

传入'C:\ test \'应返回:

C:\test\file.txt
C:\test\level2
C:\test\level3

3 个答案:

答案 0 :(得分:0)

希望这有帮助

DECLARE @SearchDir VARCHAR(4000) 
SET @SearchDir = 'C:\test\' 

;WITH cte_TestData(Directory) AS
(
SELECT 'C:\test\file.txt' UNION ALL
SELECT 'C:\test2\file.txt' UNION ALL
SELECT 'C:\test\level2\bc.txt' UNION ALL
SELECT 'C:\test\level3\another.txt' UNION ALL
SELECT 'C:\test\level1\level2\bc.txt' UNION ALL
SELECT 'C:\test\level1\level2\level3\another.txt'
)
SELECT CASE 
        WHEN CHARINDEX('\', REPLACE(Directory, @SearchDir, '')) > 0
            THEN @SearchDir + LEFT(REPLACE(Directory, @SearchDir, ''), CHARINDEX('\', REPLACE(Directory, @SearchDir, '')) - 1)
        ELSE @SearchDir + REPLACE(Directory, @SearchDir, '')
        END
FROM cte_TestData
WHERE CHARINDEX(@SearchDir, Directory) > 0
    AND LEN(REPLACE(Directory, @SearchDir, '')) - LEN(REPLACE(REPLACE(Directory, @SearchDir, ''), '\', '')) <= 1

答案 1 :(得分:0)

与Gouri的解决方案类似

DECLARE @SearchDir VARCHAR(4000) 
SET @SearchDir = 'C:\test\' 

;WITH cte_TestData(Directory) AS
(
SELECT 'C:\test\file.txt' UNION ALL
SELECT 'C:\test2\file.txt' UNION ALL
SELECT 'C:\test\level2\bc.txt' UNION ALL
SELECT 'C:\test\level3\another.txt' UNION ALL
SELECT 'C:\test\level1\level2\bc.txt' UNION ALL
SELECT 'C:\test\level1\level2\level3\another.txt'
)
SELECT * FROM cte_TestData
WHERE PATINDEX('%\%',REPLACE(Directory,@SearchDir,'')) = 0 --remove the @searchDir filter and what remains shouldnt containa backslash

答案 2 :(得分:0)

这就是诀窍。包含OrderBy以在文件夹名称之前输出文件名。如果您不关心订单,可以放弃订单和order by条款。

-- Sample data.
declare @Filenames as Table ( Filename VarChar(128) );
insert into @Filenames ( Filename ) values
  ( 'C:\test\file.txt' ), ( 'C:\test\level2\file.txt' ),
  ( 'C:\test\level2\bc.txt' ), ( 'C:\test\level3\another.txt' ),
  ( 'C:\test\level3\deeper\nothing.txt' );
select * from @Filenames;

declare @Path as VarChar(128) = 'C:\test\';

-- Get the files.
--   Filename longer than   @Path , but not containing an additional reverse solidus ('\').
select Filename, 1 as OrderBy
  from @Filenames
  where Filename like @Path + '%' and Filename not like @Path + '%\%'
union
-- Get the directories.
--   Filename longer than   @Path   and containing one additional reverse solidus ('\').
--   Locate the reverse solidus after the length of   @Path   and trim from that point onwards.
--   Since there may be many files in each folder, use   distinct   to get each folder once.
select distinct SubString( Filename, 1, CharIndex( '\', Filename, Len( @Path ) + 1 ) - 1 ), 2
  from @Filenames
  where Filename like @Path + '%\%' and Filename not like @Path + '%\%\%'
order by OrderBy, Filename;