PATHNAME: примеры (SQL)

Функция PATHNAME: работа с файловыми путями в SQL Server
Раздел: Функции работы с FileStream
PATHNAME: nvarchar(max)

Описание функции PATHNAME

Функция PATHNAME в MS SQL Server используется исключительно в контексте FileTables — специальных таблиц для хранения файлов и папок в базе данных с использованием технологии FILESTREAM. Она возвращает путь к файлу или папке в иерархии FileTable. Функция позволяет получить логический или UNC-путь без необходимости прямого доступа к файловой системе.

Функция применяется, когда требуется получить путь к элементу (файлу или каталогу), хранящемуся в FileTable, для дальнейшего использования в приложениях, отчетах или интеграционных процессах.

Синтаксис функции: PATHNAME ( [ column_name ] )

  • column_name (необязательный аргумент): имя столбца типа FILESTREAM в FileTable. Если аргумент опущен, функция возвращает путь к корневой директории FileTable. При указании столбца возвращается путь к конкретному файлу, связанному со строкой.

Возвращаемое значение: строка типа nvarchar(max), представляющая путь. Формат пути зависит от конфигурации FileTable (логический путь относительно корня FileTable или полный UNC-путь).

Короткие примеры использования

Пример 1: Получение пути к корневой папке FileTable.

SELECT PATHNAME() AS RootPath
FROM MyFileTable
WHERE is_directory = 1 AND parent_path_locator IS NULL;
RootPath
--------------------------------------
/

Пример 2: Получение UNC-путей для всех файлов в FileTable.

SELECT name, PATHNAME(file_stream) AS FilePath
FROM MyFileTable
WHERE is_directory = 0;
name      FilePath
--------- ----------------------------------------------
doc1.docx \\SERVER\MSSQLSERVER\MyFileTableDB\Folder\doc1.docx
image.jpg \\SERVER\MSSQLSERVER\MyFileTableDB\Folder\image.jpg

Пример 3: Получение относительного логического пути.

SELECT name, PATHNAME() AS RelativePath
FROM MyFileTable
WHERE is_directory = 1;
name        RelativePath
----------- --------------
Documents  /Documents
Reports    /Documents/Reports

Похожие функции в MS SQL

В MS SQL Server существуют функции для работы с иерархическими данными и путями:

  • GetPathName() (метод типа hierarchyid): Возвращает строковое представление пути для узла в иерархии. Используется для данных, организованных в древовидную структуру (например, отделы в организации). Предпочтительнее для работы с иерархическими данными, не связанными с файлами.
  • FileTableRootPath(): Возвращает корневой путь FileTable на уровне базы данных или таблицы. Полезен для получения базового пути, к которому можно добавлять относительные пути.

Функцию PATHNAME следует выбирать для непосредственного получения путей к файлам и папкам внутри FileTable, в то время как GetPathName() применяется для общих иерархий, а FileTableRootPath() — для конфигурационных задач.

Типичные ошибки

Ошибка 1: Использование функции не в контексте FileTable.

-- Создание обычной таблицы без FileTable
CREATE TABLE RegularTable (id INT);
SELECT PATHNAME() FROM RegularTable; -- Ошибка
Msg 208, Level 16, State 1: Invalid object name 'RegularTable'.

Ошибка 2: Попытка указать несуществующий столбец FILESTREAM.

-- Предположим, столбец 'file_data' не существует
SELECT PATHNAME(file_data) FROM MyFileTable;
Msg 207, Level 16, State 1: Invalid column name 'file_data'.

Ошибка 3: Вызов функции без предварительного включения FILESTREAM и создания FileTable. Необходимо убедиться, что база данных сконфигурирована для FILESTREAM.

Изменения в последних версиях

Функция PATHNAME была введена в SQL Server 2012 вместе с технологией FileTable. С тех пор существенных изменений в её синтаксисе или поведении не было. Однако, в более новых версиях SQL Server (например, 2016 и выше) улучшена интеграция FileTable с другими компонентами, такими как PolyBase и система безопасности, но сама функция осталась неизменной.

Расширенные примеры

Пример 1: Поиск файлов по расширению с использованием пути.

Пример sql
SELECT name, PATHNAME(file_stream) AS FullPath
FROM MyFileTable
WHERE is_directory = 0 AND name LIKE '%.pdf';
name            FullPath
--------------- --------------------------------------------------
manual.pdf      \\SERVER\MSSQLSERVER\MyDB\Documents\manual.pdf
report.pdf      \\SERVER\MSSQLSERVER\MyDB\Documents\report.pdf

Пример 2: Рекурсивный поиск в подпапках FileTable с использованием иерархии.

Пример sql
WITH FileHierarchy AS (
    SELECT name, path_locator, PATHNAME() AS Path, is_directory
    FROM MyFileTable
    WHERE parent_path_locator IS NULL
    UNION ALL
    SELECT f.name, f.path_locator, 
           h.Path + '/' + f.name,
           f.is_directory
    FROM MyFileTable f
    INNER JOIN FileHierarchy h ON f.parent_path_locator = h.path_locator
)
SELECT * FROM FileHierarchy WHERE is_directory = 0;
name        path_locator Path                          is_directory
----------- ------------ ----------------------------- ------------
data.txt    0x7AD0...    /Folder/SubFolder/data.txt    0

Пример 3: Обновление путей в приложении путем извлечения директории.

Пример sql
SELECT name, 
       REVERSE(SUBSTRING(REVERSE(PATHNAME(file_stream)), 
                         CHARINDEX('\\', REVERSE(PATHNAME(file_stream)))+1, 
                         LEN(PATHNAME(file_stream)))) AS Directory
FROM MyFileTable;
name        Directory
----------- --------------------------------------------
test.docx   \\SERVER\MSSQLSERVER\MyDB\Documents\

Пример 4: Интеграция с xp_cmdshell для проверки существования файла (требует прав).

Пример sql
DECLARE @cmd NVARCHAR(1000);
SET @cmd = 'IF EXIST "' + (SELECT TOP 1 PATHNAME(file_stream) 
                           FROM MyFileTable WHERE name = 'important.txt') + '" ECHO File exists';
EXEC xp_cmdshell @cmd;

Альтернативы в других СУБД и языках

Прямых аналогов функции PATHNAME в других СУБД нет, так как она специфична для FileTable MS SQL. Однако, для работы с путями файлов в базах данных существуют другие подходы:

  • PostgreSQL (Large Objects): Для доступа к большим объектам используется API (например, lo_export), но пути возвращаются на стороне клиента. Пример получения OID (идентификатора объекта):
    SELECT oid FROM pg_largeobject_metadata WHERE loid = 12345;
  • Oracle (BFile): Тип BFILE хранит указатель на внешний файл. Для получения пути используется функция BFILENAME:
    SELECT BFILENAME('MEDIA_DIR', 'image.png') AS file_loc FROM dual;
    file_loc
    ----------------------------------------------------
    BFILE('MEDIA_DIR', 'image.png')
  • MySQL: Не имеет встроенной файловой таблицы. Обычно пути хранятся в текстовых столбцах, а файлы — в файловой системе.
  • Язык программирования (например, C#): При работе с SQL можно получать путь через данные FileTable, а затем использовать класс System.IO.Path для манипуляций.

MS SQL PATHNAME function comments

En
PATHNAME Returns the path of a FILESTREAM binary large object (BLOB)