2017-03-27 101 views
-1

我有一個在sql server中存儲爲路徑的大量文件列表。將路徑分成多個目錄很容易,但是,我需要能夠一次顯示一個級別上的所有文件和文件夾的列表。 SQL Server有一些內置的實用程序來處理服務器本地的文件,但在這種情況下它們不適用。使用T-SQL生成基於目錄的目錄和文件列表

使用通配符將返回當前目錄下的所有內容,所以我放棄了這一點。

數據:

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

理想情況下,我想一個文件夾中傳遞,並查看所有文件和文件夾在這一水平。然後我可以在樹形控件中展示它,但這部分不在問題的範圍之內。

在傳承 'C:\測試\' 應該返回:

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

'SELECT filename FROM datatable WHERE filename LIKE'C:\ test \%''? –

+0

'其中的文件名像@Path +'%'和文件名不像@Path +'%\%'',即所需的級別但不是更深的所有內容都將獲取文件而不是文件夾。你可以'聯合'一個類似的查詢來獲取文件夾。 – HABO

+0

HABO - 謝謝,這讓我親密!只需要弄清楚現在只有如何獲取目錄。 – Proteus

回答

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; 
+0

非常感謝,這個作品! – Proteus

+0

仍在使用此代碼 - 僅在文件夾下有文件目錄時才返回文件夾。如果有一個文件夾更低一級但沒有文件,它不會返回任何內容。 – Proteus

+0

你的意思是,如果你搜索「C:\ foo \」並且有一個空目錄匹配,那麼該目錄不會被輸出?如果「C:\ foo \」和尾部的反向固體(「\」)在表中,那麼它將被選中。 ''C:\ foo''在所有外觀上都是根文件夾中沒有類型而不是文件夾的文件。 – HABO

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 
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