Статьи

Запрос файловой системы — от ColdFusion до SQL Server

В поисках решения другой проблемы я понял, что в SQL Server есть функция, называемая расширенными хранимыми процедурами. Расширенные хранимые процедуры, по крайней мере, в SQL Server 2000, должны быть написаны на C ++ и скомпилированы в DLL. Хорошим примером такой процедуры является моя предыдущая статья об использовании регулярных выражений в SQL Server . Я не буду вдаваться в подробности написания расширенных хранимых процедур в этой статье, так как мои навыки C ++ в лучшем случае ржавые. Вместо этого я расскажу об использовании существующей хранимой процедуры для запроса файловой системы и о том, как перейти от использования ColdFusion к использованию SQL Server.

Использование ColdFusion

Получение списка файлов в ColdFusion довольно тривиально. Все, что вам нужно сделать, это использовать тег «<cfdirectory>» следующим образом:

<cfset localDirectoryPath = "C:\Temp" />

<cfdirectory
name="textFiles"
action="list"
filter="*.txt"
directory="#localDirectoryPath#" />

Это позволит получить список всех файлов с расширением «.txt» в каталоге «C: \ Temp».

Получение списка файлов с сетевого диска ничем не отличается, за исключением указания сетевого пути в качестве UNC-пути (и небольшой конфигурации службы):

<cfset networkDirectoryPath = "\\larry\share" />

<cfdirectory
name="textFiles"
action="list"
filter="*.txt"
directory="#networkDirectoryPath#" />

Как указано выше, это не будет работать, если у вас не настроена служба ColdFusion для использования определенной учетной записи, которая имеет доступ к вашему сетевому пути.

Типичная настройка службы ColdFusion выглядит как на следующем снимке экрана при доступе через конфигурацию «Службы» в Windows:

Чтобы иметь возможность запрашивать сетевой путь, вам нужно указать пользователя, который имеет доступ к этому сетевому пути:

Использование SQL Server

Настройка для использования SQL Server для запроса сетевых путей такая же, как и для ColdFusion:

Настройка по умолчанию Но должно быть что-то вроде

Если вы не настроите SQL Server для запуска от имени соответствующего пользователя, пытаясь запросить сетевой путь с помощью метода, представленного здесь, вы получите ошибку отказа в доступе:

Помимо этого, я написал пользовательские хранимые процедуры на основе встроенной расширенной хранимой процедуры «xp_cmdshell». Эта процедура вернет запрос со следующим:

  • fileID — уникальное автоматически увеличенное целое значение
  • fileName — имя файла
  • lastModifiedOn — дата последнего изменения файла
  • fileSize — размер файла в байтах

Вот результаты запроса локального пути «C: \ Temp» без фильтра расширений файлов:

exec dbo.getDirectoryFileList 'c:\temp', null

После настройки процедура также может работать на сетевых дисках, например, чтобы возвращать только файлы с расширением «.btw»:

exec dbo.getDirectoryFileList '\\larry\indium\Production\labelGeneration', '*.btw'

Покажи мне код

/*
Type: Stored Procedure
Name: dbo.getDirectoryFileList
Author: Boyan Kostadinov
Created: 03.17.2008
Dependencies: master.dbo.xp_cmdshell
Usage: exec dbo.getDirectoryFileList 'c:\temp', null
exec dbo.getDirectoryFileList '\\larry\indium\Production\labelGeneration', '*.btw'
Parameters: @directoryPath varchar(255)
- The path of the local or network directory

@fileExtensionFilter varchar(10) - Optional
- The file extension to filter the file list by
Returns: A list of files found on the file system
*/
create procedure dbo.getDirectoryFileList
@directoryPath varchar(255),
@fileExtensionFilter varchar(10) = null
as

set nocount on

-- Declare and initialize local variables
declare @dosCommand varchar(5000)
set @dosCommand = ''

-- If the file extension fileter was empty, set it to all files
if @fileExtensionFilter is null or ltrim(rtrim(@fileExtensionFilter)) = ''
set @fileExtensionFilter = '*.*'

-- If the directory path does not have an ending '\', append one
if substring(@directoryPath, len(@directoryPath), 1) <> '\'
set @directoryPath = @directoryPath + '\'

-- Build the dos command to get a list of files
select @dosCommand =
'insert into #tempFileList(fileListRow) ' +
'exec master.dbo.xp_cmdshell ''dir ' + @directoryPath + + @fileExtensionFilter + ''''

-- Create a temporary table to store the file list
create table #tempFileList (
fileListRow varchar(1000) null
)

-- Create the #fileList temporary table to store the file list
create table #fileList (
fileID int primary key identity(1,1) not null,
[fileName] varchar(255) not null,
lastModifiedOn datetime not null,
fileSize bigint not null,
)

exec(@dosCommand)

-- 8 - Delete unneeded data from the #OriginalFileList
delete from #tempFileList
where fileListRow is null

delete from #tempFileList
where fileListRow like '%Volume%'

delete from #tempFileList
where fileListRow like '%Directory%'

delete from #tempFileList
where fileListRow like '%<DIR>%'

delete from #tempFileList
where fileListRow like '%bytes%'

if not exists (select * from #tempFileList where fileListRow like '%access is denied%')
begin
-- Populate the #fileList table with the final data
insert into #fileList(lastModifiedOn, fileSize, [fileName])
select ltrim(substring(fileListRow, 1, 10))
+
' '
+
rtrim(ltrim(substring(fileListRow, 11, 15)))
+
'm'
as 'lastModifiedOn',
replace(ltrim(substring(fileListRow, 21, 18)), ',', '') as 'fileSize',
ltrim(substring(fileListRow, 40, 1000)) as 'fileName'
from #tempFileList

select * from #fileList
end
else
select fileListRow as errorMessage from [#tempFileList] as e

-- Drop the temporary tables
drop table #tempFileList
drop table #fileList

set nocount off
go

Скачать

Вы можете загрузить хранимую процедуру с http://tech-cats.net/blog/downloads/sql/getDirectoryFileList.txt.

Рекомендации

Доступ к файловой системе Windows из SQL Server