В поисках решения другой проблемы я понял, что в 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.