如何使用SQL Server列出文件夹中的文件

Joh*_*isi 45 sql sql-server

如何在不使用xp_cmdshell存储过程的情况下在SQL Server中的文件夹中列出文件?

Mat*_*cic 66

您可以使用xp_dirtree

它需要三个参数:

根目录的路径, 深度达要获得文件和文件夹,最后一个是只显示文件夹或文件夹和文件.

例: EXEC xp_dirtree 'C:\', 2, 1


小智 29

可以使用xp_DirTree完成,然后循环以生成完整的文件路径(如果需要).

以下是我用于将数据库自动还原到测试服务器的脚本的摘录.它会扫描文件夹和所有子文件夹中的任何备份文件,然后返回完整路径.


  DECLARE @BackupDirectory SYSNAME = @BackupFolder

  IF OBJECT_ID('tempdb..#DirTree') IS NOT NULL
    DROP TABLE #DirTree

  CREATE TABLE #DirTree (
    Id int identity(1,1),
    SubDirectory nvarchar(255),
    Depth smallint,
    FileFlag bit,
    ParentDirectoryID int
   )

   INSERT INTO #DirTree (SubDirectory, Depth, FileFlag)
   EXEC master..xp_dirtree @BackupDirectory, 10, 1

   UPDATE #DirTree
   SET ParentDirectoryID = (
    SELECT MAX(Id) FROM #DirTree d2
    WHERE Depth = d.Depth - 1 AND d2.Id < d.Id
   )
   FROM #DirTree d

  DECLARE 
    @ID INT,
    @BackupFile VARCHAR(MAX),
    @Depth TINYINT,
    @FileFlag BIT,
    @ParentDirectoryID INT,
    @wkSubParentDirectoryID INT,
    @wkSubDirectory VARCHAR(MAX)

  DECLARE @BackupFiles TABLE
  (
    FileNamePath VARCHAR(MAX),
    TransLogFlag BIT,
    BackupFile VARCHAR(MAX),    
    DatabaseName VARCHAR(MAX)
  )

  DECLARE FileCursor CURSOR LOCAL FORWARD_ONLY FOR
  SELECT * FROM #DirTree WHERE FileFlag = 1

  OPEN FileCursor
  FETCH NEXT FROM FileCursor INTO 
    @ID,
    @BackupFile,
    @Depth,
    @FileFlag,
    @ParentDirectoryID  

  SET @wkSubParentDirectoryID = @ParentDirectoryID

  WHILE @@FETCH_STATUS = 0
  BEGIN
    --loop to generate path in reverse, starting with backup file then prefixing subfolders in a loop
    WHILE @wkSubParentDirectoryID IS NOT NULL
    BEGIN
      SELECT @wkSubDirectory = SubDirectory, @wkSubParentDirectoryID = ParentDirectoryID 
      FROM #DirTree 
      WHERE ID = @wkSubParentDirectoryID

      SELECT @BackupFile = @wkSubDirectory + '\' + @BackupFile
    END

    --no more subfolders in loop so now prefix the root backup folder
    SELECT @BackupFile = @BackupDirectory + @BackupFile

    --put backupfile into a table and then later work out which ones are log and full backups  
    INSERT INTO @BackupFiles (FileNamePath) VALUES(@BackupFile)

    FETCH NEXT FROM FileCursor INTO 
      @ID,
      @BackupFile,
      @Depth,
      @FileFlag,
      @ParentDirectoryID 

    SET @wkSubParentDirectoryID = @ParentDirectoryID      
  END

  CLOSE FileCursor
  DEALLOCATE FileCursor
Run Code Online (Sandbox Code Playgroud)


Rem*_*anu 7

创建具有外部访问权限的SQLCLR程序集,该权限将文件列表作为结果集返回.有很多例子如何做到这一点,例如.另一个TVF:从目录返回文件在xp_cmdshell中交易SQLCLR(第1部分) - 列出目录内容.


Eoi*_*ell 6

如果需要,可以使用CLR功能/组件来实现。

  1. 创建一个SQL Server CLR组装项目。
  2. 转到属性,并确保将连接上的权限级别设置为外部
  3. 向程序集添加一个Sql函数。

这是一个示例,可让您从表格中选择结果集。

public partial class UserDefinedFunctions
{
    [SqlFunction(DataAccess = DataAccessKind.Read,
        FillRowMethodName = "GetFiles_FillRow", TableDefinition = "FilePath nvarchar(4000)")]
    public static IEnumerable GetFiles(SqlString path)
    {
        return System.IO.Directory.GetFiles(path.ToString()).Select(s => new SqlString(s));
    }

    public static void GetFiles_FillRow(object obj,out SqlString filePath)
    {
        filePath = (SqlString)obj;
    }
};
Run Code Online (Sandbox Code Playgroud)

还有你的SQL查询。

use MyDb

select * From GetFiles('C:\Temp\');
Run Code Online (Sandbox Code Playgroud)

但是请注意,您的数据库需要使用以下SQL命令启用CLR程序集功能。

sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO
Run Code Online (Sandbox Code Playgroud)

CLR程序集(如XP_CMDShell)默认情况下处于禁用状态,因此,如果不使用XP Cmd Shell的原因是由于您没有权限,那么您也可能会选择使用此选项……仅供参考。

  • 不。您被困住了...默认情况下,任何允许SQL Server从外部访问资源而不进行处理的东西都会被锁定。 (2认同)