복붙노트

[SQL] 어떻게 목록 파일에 SQL 서버의 폴더 내부

SQL

어떻게 목록 파일에 SQL 서버의 폴더 내부

어떻게 xp_cmdshell을 저장 프로 시저를 사용하지 않고 SQL Server에서 폴더 내의 파일 목록을합니까?

해결법

  1. ==============================

    1.당신은 xp_dirtree을 사용할 수 있습니다

    당신은 xp_dirtree을 사용할 수 있습니다

    그것은 세 가지 매개 변수를 사용합니다

    루트 디렉토리의 경로, 파일과 폴더를 취득하는에 깊이 위로 마지막 하나는 폴더와 파일 또는 둘 모두를 폴더를 표시하기위한 것입니다.

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

  2. ==============================

    2.다음 필요한 경우 전체 파일 경로를 생성 통해 반복, xp_DirTree를 사용하여 수행 할 수 있습니다.

    다음 필요한 경우 전체 파일 경로를 생성 통해 반복, 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
    
  3. ==============================

    3.결과 세트로 파일 목록을 반환 외부 액세스 권한이있는 어셈블리 SQLCLR을 만듭니다. 예를 들어,이 작업을 수행하는 방법에 많은 사례가있다. 또 다른 TVF : SQLCLR에 대한 xp_cmdshell을의 디렉토리 또는 거래에서 반환 파일 (1 부) - 목록 디렉토리 내용.

    결과 세트로 파일 목록을 반환 외부 액세스 권한이있는 어셈블리 SQLCLR을 만듭니다. 예를 들어,이 작업을 수행하는 방법에 많은 사례가있다. 또 다른 TVF : SQLCLR에 대한 xp_cmdshell을의 디렉토리 또는 거래에서 반환 파일 (1 부) - 목록 디렉토리 내용.

  4. ==============================

    4.당신이 원하는 경우에 당신은 CLR 기능 / 조립을 사용하여이 작업을 수행 할 수 있습니다.

    당신이 원하는 경우에 당신은 CLR 기능 / 조립을 사용하여이 작업을 수행 할 수 있습니다.

    다음은 테이블처럼 결과 세트를 형성 선택할 수 있습니다 예입니다.

    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;
        }
    };
    

    그리고 당신의 SQL 쿼리.

    use MyDb
    
    select * From GetFiles('C:\Temp\');
    

    인식하지만 만나, 데이터베이스는 다음과 같은 SQL 명령을 사용하여 활성화 CLR 어셈블리 functionaliy을 가질 필요가있다.

    sp_configure 'clr enabled', 1
    GO
    RECONFIGURE
    GO
    

    (xp_cmdshell을 같은) CLR 어셈블리는 XP Cmd를 셸을 사용하지 않는 이유는 권한이 없으므로, 당신은 단지 참고하시기 바랍니다 ... 물론이 옵션으로 붙어있을 수 있습니다 그렇다면 기본적으로 비활성화되어 있습니다.

  5. ==============================

    5.좀 터무니없이 복잡 CLR 솔루션 그래서 내 자신의 간단한의 VB 하나를 쓰기로 결정 발견이와 결국 괜찮은 쉬운 해결책을 찾기 위해 연령대에 주변에 사냥. 간단하게 설치된 템플릿에서 데이터베이스 탭에서 새 VB의 CLR 프로젝트를 생성 한 다음 새 SQL CLR VB 사용자 정의 함수를 추가합니다. 나는 CLRGetFilesInDir.vb에 이름. 여기 내부의 코드는 ...

    좀 터무니없이 복잡 CLR 솔루션 그래서 내 자신의 간단한의 VB 하나를 쓰기로 결정 발견이와 결국 괜찮은 쉬운 해결책을 찾기 위해 연령대에 주변에 사냥. 간단하게 설치된 템플릿에서 데이터베이스 탭에서 새 VB의 CLR 프로젝트를 생성 한 다음 새 SQL CLR VB 사용자 정의 함수를 추가합니다. 나는 CLRGetFilesInDir.vb에 이름. 여기 내부의 코드는 ...

    Imports System
    Imports System.Data
    Imports System.Data.Sql
    Imports System.Data.SqlTypes
    Imports Microsoft.SqlServer.Server
    Imports System.IO
    -----------------------------------------------------------------------------
    Public Class CLRFilesInDir
    -----------------------------------------------------------------------------
    <SqlFunction(FillRowMethodName:="FillRowFiles", IsDeterministic:=True, IsPrecise:=True, TableDefinition:="FilePath nvarchar(4000)")> _
    Public Shared Function GetFiles(PathName As SqlString, Pattern As SqlString) As IEnumerable
        Dim FileNames As String()
    
        Try
        FileNames = Directory.GetFiles(PathName, Pattern, SearchOption.TopDirectoryOnly)
        Catch
            FileNames = Nothing
        End Try
    
        Return FileNames
    
    End Function
    -----------------------------------------------------------------------------
    Public Shared Sub FillRowFiles(ByVal obj As Object, ByRef Val As SqlString)
        Val = CType(obj, String).ToString
    End Sub
    
    End Class
    

    또한 CLRExcelFiles에 프로젝트 속성 창에서 어셈블리 이름을 변경하고, 기본 네임 스페이스 CLRGetExcelFiles합니다.

    참고 : 당신은 아무것도를 사용하는 경우 3.5 대상 프레임 워크를 설정 덜 SQL 서버 2012이.

    프로젝트를 컴파일하고 C와 같은 곳으로 \ 빈 \ 릴리스에서 CLRExcelFiles.dll 복사 : \ 온도를 SQL 서버 시스템에서, 자신 없습니다.

    에서 SSMS -

    CREATE ASSEMBLY <your assembly name in here - anything you like>
    FROM 'C:\temp\CLRExcelFiles.dll';
    
    CREATE FUNCTION dbo.fnGetFiles
    (
    @PathName NVARCHAR(MAX),
    @Pattern NVARCHAR(MAX)
    )
    RETURNS TABLE (Val NVARCHAR(100))
    AS
    EXTERNAL NAME <your assembly name>."CLRGetExcelFiles.CLRFilesInDir".GetFiles;
    GO
    

    다음 전화

    SELECT * FROM dbo.fnGetFiles('\\<SERVERNAME>\<$SHARE>\<folder>\' , '*.xls')
    

    참고 : 나는이 프로젝트 속성에서 SQLCLR 탭에서 EXTERNAL_ACCESS에 권한 레벨을 변경하더라도, 나는 아직도 I (재)를 만든이 모든 시간을 실행하는 데 필요한.

    ALTER ASSEMBLY [CLRFilesInDirAssembly] 
    WITH PERMISSION_SET = EXTERNAL_ACCESS 
    GO
    

    및 wullah! 그 작동합니다.

  6. ==============================

    6.아주 쉽게, 바로 SQLCMD 구문을 사용합니다.

    아주 쉽게, 바로 SQLCMD 구문을 사용합니다.

    > SQLCMD 모드 -의 SSMS에서 SQLCMD 모드를 활성화 쿼리에서보고 기억

    실행하십시오 :

    SAY! ! : GO

    아니면 :     !! DIR "C : / TEMP"     !!:가다

  7. from https://stackoverflow.com/questions/11559846/how-to-list-files-inside-a-folder-with-sql-server by cc-by-sa and MIT license