简体   繁体   中英

Querying path structure information using SQL Server

Consider I have a table with a lot of paths like:

  • \\test
  • \\test\\file.txt
  • \\test\\file2.txt
  • \\file3.txt
  • \\test\\subfolder\\anotherfolder\\test.txt

How would perform a SELECT query that accurately represents the folder and file structure?

  • test (folder)
  • file3.txt (file)

and then querying on the "test" folder should give

  • subfolder (folder)
  • file.txt (file)
  • file2.txt (file)

Every item in the table knows if it is a directory or a file.

Here's a solution where it is assumed the table has a column indicating whether an item is a folder. Folder items in the table should not end with '\\'.

DECLARE @dir varchar(300);
SET @dir = '\test\';

SELECT
  dir_item = CASE diritem WHEN '' THEN '.' ELSE dir_item END,
  is_folder
FROM (
  SELECT
    dir_item,
    is_folder
  FROM (
    SELECT
      dir_item = STUFF(path_item, 1, LEN(@dir), ''),
      is_folder
    FROM paths
    WHERE SUBSTRING(path, 1, LEN(@dir)) = @dir
  ) s
  WHERE CHARINDEX('\', dir_item) = 0
) s
ORDER BY is_folder DESC, dir_item;

see this blog about convert_anything_to_tree_structures_in_php .
The example covers a similar problem and provides a solution in php.
(doesn't mean you have to do it with php but you may adopt the idea/algorithm)

BW's PHP link would be good to check out, but if you'd like to stick to SQL, try this UDF. Given an input string, it will split it on a specified separator, returning one row per item.

CREATE FUNCTION dbo.Split(@Input VARCHAR(MAX), @Separator CHAR(1))
  RETURNS TABLE
AS RETURN
  WITH A AS
    (
    SELECT 1 AS Sequence, CAST(1 AS BIGINT) AS StartChar, CHARINDEX(@Separator, @Input) AS EndChar
    UNION ALL
    SELECT Sequence + 1, EndChar + 1, CHARINDEX(@Separator, @Input, EndChar + 1)
    FROM A
    WHERE EndChar > 0
    )
  SELECT
    Sequence,
    SUBSTRING(@Input, StartChar, CASE WHEN EndChar = 0 THEN LEN(@Input) - EndChar ELSE EndChar - StartChar END) AS Value
  FROM
    A

Example: SELECT * FROM dbo.Split('C:\\Dir\\File.ext', '\\') returns:

Sequence Value
1        C:
2        Dir
3        File.ext

This isn't a complete solution, but hopefully it will help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM