Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Lưu trữ tệp trong cơ sở dữ liệu SQL bằng FILESTREAM - Phần 2

Trong bài viết trước của tôi, tôi đã mô tả cách định cấu hình FILESTREAM trong SQL Server, tạo cơ sở dữ liệu và bảng hỗ trợ FILESTREAM. Hơn nữa, tôi đã trình bày cách chèn và xóa dữ liệu khỏi bảng FILESTREAM.

Trong bài viết này, tôi sẽ trình bày cách chèn nhiều tệp trong bảng FILESTREAM bằng T-SQL.

Trong bản trình diễn này, chúng tôi sẽ sử dụng mô-đun PowerShell để điền danh sách tệp và lưu trữ nó trong bảng SQL.

Kiểm tra cần thiết và Truy vấn Hữu ích để Nhận Cấu hình FILESTREAM

Đối với bản demo này, tôi đang sử dụng:

  1. Phiên bản SQL:SQL Server 2017
  2. Cơ sở dữ liệu: FileStream_Demo cơ sở dữ liệu
  3. Công cụ:PowerShell, SQL Server Management Studio, SQL Server Data Tools.

Trong bài viết trước của tôi, tôi đã tạo cơ sở dữ liệu có tên FileStream_Demo . Tính năng FILESTREAM được bật Trên phiên bản SQL Server và cơ sở dữ liệu có quyền cấp truy cập T-SQL và Win32.

Để xem lại cài đặt cấp độ truy cập FILESTREAM, hãy thực hiện truy vấn sau:

 Sử dụng FileStream_DemoGoSELECT Host_Name () làm 'Tên máy chủ', TÊN làm 'Cấu hình cơ sở dữ liệu', CASE WHEN value =0 THEN 'FILESTREAM bị vô hiệu hóa' WHEN value =1 THEN 'Được bật cho T-SQL' WHEN value =2 THEN ' Đã bật cho T-SQL và Win32 'END AS' FILESTREAM Option'FROM sys.configurationsWHERE NAME ='filestream access level'Go 

Đầu ra của truy vấn như sau:

Để xem lại Tệp cơ sở dữ liệu và vị trí của vùng chứa dữ liệu FILESTREAM, hãy thực hiện truy vấn sau:

 Sử dụng FileStream_DemoGoSELECT Host_Name () làm 'Tên máy chủ', TÊN làm 'Tên nhóm tệp', type_desc làm 'Loại nhóm tệp', physical_name làm 'Vị trí tệp cơ sở dữ liệu' FROM sys.database_files 

Đầu ra của truy vấn như sau:

Chèn nhiều tệp bằng SQL Script

Để chèn nhiều tệp trong bảng SQL:

  1. Tạo hai bảng SQL có tên, Document_List Document_Content . Document_Content bảng có FileStreamCol với kiểu dữ liệu VARBINARY (MAX) và thuộc tính cột FILESTREAM. Nội dung của các tệp trong thư mục sẽ được chuyển đổi trong VARBINARY (MAX) và được lưu trữ trong FileStreamCol cột Document_Content bảng.
  2. Tạo một truy vấn SQL động lặp lại qua Document_Location bảng để lấy đường dẫn của tệp và chèn tệp trong Document_Content bảng.
  3. Gói toàn bộ mã T-SQL trong một quy trình được lưu trữ.

Tạo bảng SQL

Đầu tiên, tạo một bảng tạm thời chung để lưu trữ chi tiết của các tệp. Đối với điều này, hãy thực hiện truy vấn sau trong FileStream_Demo cơ sở dữ liệu.

 SỬ DỤNG [FileStream_Demo] GOCreate table Document_List (ID int ID (1,1) Nhóm khóa chính, tên đầy đủ Varchar (max), tên Varchar (max), thuộc tính Varchar (250), CreationTime datetime, LastAccessTime datetime, LastWriteTime datetime, Độ dài số (10,2)) 

Hơn nữa, hãy tạo một bảng để lưu trữ các Tệp trong bảng. Thực thi truy vấn sau để tạo bảng vật lý:

 SỬ DỤNG [FileStream_Demo] GOCREATE TABLE [dbo]. [Document_Content] ([ID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [RootDirectory] [varchar] (max) NULL, [FileName] [varchar] (max) NULL, [ FileAttribute] [varchar] (150) NULL, [FileCreateDate] [datetime] NULL, [FileSize] [numeric] (10, 5) NULL, [FileStreamCol] [varbinary] (max) FILESTREAM NULL, UNIQUE NONCLUSTERED ([ID] ASC ) VỚI (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] FILESTREAM_ON [Dummy-Documents] GO 
 Để cải thiện hiệu suất của truy vấn đã chọn, hãy thêm chỉ mục theo nhóm trên  Tên tệp  FileType  các cột của  Document_Content  bàn. Đối với điều này, hãy thực thi đoạn mã sau:

 USE [FileStream_Demo] GOCREATE CLUSTERED INDEX [ICX_Document_Content_FileName] ON [dbo]. [Document_Content] ([FileName] ASC, [FileType] ASC) VỚI (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, SORT_IN_TEMP =OFF, SORT_IN_TEMP =OFF, SORT_IN_TEMP =OFF, SORT_IN_TEMP ONLINE =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY] FILESTREAM_ON [Dummy-Documents] GO 

Tạo mô-đun PowerShell để điền chi tiết tệp

Sau khi các bảng được tạo, hãy thực thi tập lệnh PowerShell để chèn chi tiết tệp trong Document_List bàn. Tập lệnh PowerShell chạy trong thủ tục được lưu trữ T-SQL, do đó để viết toàn bộ mã trong thủ tục SQL, bạn cần tạo một hàm PowerShell. Đường dẫn thư mục là một tham số đầu vào bắt buộc của hàm. Tập lệnh lấy danh sách các tệp, nằm trong tham số thư mục được sử dụng để thực thi chức năng PowerShell.

Mã như sau:

  1. Tạo một hàm và khai báo các tham số đầu vào bắt buộc. Đoạn mã như sau:
     function global:getFileList {param ([Tham số (Vị trí =0, bắt buộc =$ true)] [string []] $ FilePath) 
  2. Tạo một chuỗi có truy vấn "Chèn". Xem đoạn mã sau:
     [email protected]'INSERT INTO ## Document_List (đầy đủ, tên, thuộc tính, CreationTime, LastAccessTime, LastWriteTime, Length) VALUES ('{0}', '{1}', '{ 2} ',' {3} ',' {4} ',' {5} ',' {6} ')' @ 
  3. Lấy danh sách các tệp bằng lệnh Get-ChildItem -Recurse định dạng đầu ra của lệnh. Đoạn mã như sau:
     Get-ChildItem -Recurse $ Directorypath | select @ {Label ="FullName"; Expression ={split-path ($ _. FullName)}}, tên, thuộc tính, CreationTime, LastAccessTime, LastWriteTime, @ {Label ="Length"; Expression ={$ _. Length / 1MB -as [int]}} 
  4. Sử dụng vòng lặp For-Each, lưu trữ kết quả đầu ra trong Document_content bàn. Để chạy truy vấn trên FileStream_Demo cơ sở dữ liệu, tập lệnh sử dụng Invoke-Sqlcmd . Đoạn mã như sau:
     ForEach-Object {$ SQL =$ sqltmplt -f $ _. FullName, $ _. Name, $ _. Thuộc tính, $ _. CreationTime, $ _. LastAccessTime, $ _. LastWriteTime, $ _. Length Invoke-sqlcmd -Query $ SQL -ServerInstance TTI412-VM \ SQL2017 -database FileStream_Demo} 

Toàn bộ mã của hàm PowerShell sẽ giống như sau:

Hàm
 global:getFileList {param ([Tham số (Vị trí =0, bắt buộc =$ true)] [string []] $ FilePath) Ghi-Đầu ra "Chèn tệp" [email protected]'INSERT INTO dbo.Document_List ( fullname, name, thuộc tính, CreationTime, LastAccessTime, LastWriteTime, Length) GIÁ TRỊ ('{0}', '{1}', '{2}', '{3}', '{4}', '{5} ',' {6} ')' @ Invoke-Sqlcmd -Query "Truncate Table Document_List" -ServerInstance TTI412-VM \ SQL2017 -database FileStream_DemoGet-ChildItem -Recurse $ FilePath | select @ {Label ="FullName"; Expression ={split-path ($ _. FullName)}}, tên, thuộc tính, CreationTime, LastAccessTime, LastWriteTime, @ {Label ="Length"; Expression ={$ _. Length / 1MB -as [int]}} | ForEach-Object {$ SQL =$ sqltmplt -f $ _. FullName, $ _. Name, $ _. Thuộc tính, $ _. CreationTime, $ _. LastAccessTime, $ _. LastWriteTime, $ _. Length Invoke-sqlcmd -Query $ SQL -ServerInstance TTI412-VM \ SQL2017 -database FileStream_Demo} Write-Output "Đã chèn tệp thành công ... Dưới đây là danh sách các tệp."} 

Để sử dụng chức năng PowerShell trong thủ tục SQL Stored, chúng ta cần đăng ký tập lệnh trên dưới dạng Mô-đun PowerShell. Đối với điều này, hãy tạo một thư mục có tên getFileList tại C:\ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules . Để đăng ký bất kỳ tập lệnh PowerShell nào dưới dạng mô-đun, tập lệnh và tên thư mục phải giống nhau. Do đó, hãy lưu tập lệnh trên dưới dạng getFileList.psm1 trong getFileList thư mục.

Bây giờ, khi chúng tôi thực thi tập lệnh PowerShell từ T-SQL, chúng tôi cần nhập getFileList mô-đun. Đối với điều này, hãy thêm mã sau vào cấu hình PowerShell. Cấu hình PowerShell sẽ được tạo tại C:\ Windows \ System32 \ WindowsPowerShell \ v1.0 vị trí.

 import-module getFileList 

Nếu cấu hình không tồn tại, hãy thực hiện lệnh sau để tạo cấu hình.

 New-Item -Type File -Path $ PROFILE.AllUsersAllHosts -Force 

Tạo một thủ tục đã lưu trữ để nhập tệp

Khi chúng tôi lưu trữ danh sách tệp và thông tin trong Bảng SQL, chúng tôi sẽ chèn các tệp vào Document_Content bảng.

Để thực hiện tác vụ này một cách hiệu quả, hãy tạo một thủ tục được lưu trữ được tham số hóa có tên là sp_Insert_Documents . Nó sẽ sử dụng FileLocation tham số của kiểu dữ liệu varchar. Quy trình điền danh sách các tệp từ vị trí được cung cấp trong tham số và chèn tất cả các tệp trong Document_Content bảng.

Bước 1:Thay đổi thông số cấu hình.

Để chạy lệnh PowerShell bằng T-SQL, hãy bật xp_cmdshell tùy chọn cấu hình. Nó là một tùy chọn cấu hình nâng cao; do đó trước khi bật xp_cmdshell , bật tùy chọn Hiển thị tùy chọn nâng cao tùy chọn cấu hình. Đối với điều này, hãy thực hiện các lệnh T-SQL sau theo trình tự.

 sử dụng mastergoexec sp_configure 'hiển thị tùy chọn nâng cao', 1 cấu hình với ghi đèExec sp_configure 'xp_cmdshell', 1Reconfigure với ghi đè 

Bước 2:Sử dụng tập lệnh PowerShell để điền danh sách tệp trong mã T-SQL

Để thực thi tập lệnh PowerShell bằng T-SQL, hãy sử dụng xp_cmdshell thủ tục. Nó thực thi lệnh PowerShell, sẽ điền danh sách các tệp và thông tin chi tiết của nó trong Document_List bảng.
Mã như sau:

 khai báo @PSScript varchar (2500) set @ PSScript ='powershell.exe getFileList' '' + @FileLoc + '' '' execute xp_cmdshell @PSScript 

Bước 3:Tạo truy vấn SQL động để lấy vị trí tệp

Tạo một truy vấn SQL động lặp lại qua Document_List , tải nội dung của tệp, nằm ở đường dẫn được cung cấp trong Tên đầy đủ , chuyển đổi nó thành cột VARBINAR (MAX) và chèn nó vào Document_Content bàn. Cùng với Tệp, tập lệnh chèn Tên tệp, thuộc tính Tệp, Kích thước tệp và Loại tệp vào Document_Content bàn. Tập lệnh sử dụng trường hợp biểu thức để xác định loại tệp.

Mã như sau:

 SET @FileCount =(SELECT Count (*) FROM Document_List) WHILE (@i <@FileCount) BEGIN SET @FileName =(SELECT TOP 1 name FROM Document_List) / * Nối cột DirectoryLocation và FileName để tạo FQDN. * / SET @FileName =(CHỌN TOP 1 tên TỪ Document_List) SET @FileLocation =(CHỌN 1 tên đầy đủ TỪ Document_List trong đó name =@FileName) SET @FileAttribute =(CHỌN TOP 1 thuộc tính TỪ Document_List trong đó name =@FileName) SET @ FileCreateDate =(CHỌN TOP 1 CreationTime TỪ Document_List trong đó name =@FileName) SET @FileSize =(CHỌN ĐẦU 1 Độ dài TỪ Document_List trong đó name =@FileName) SET @FileType =(CHỌN HÀNG ĐẦU 1 TRƯỜNG HỢP KHI (tên LIKE '% jpg%' ) HOẶC (tên LIKE '% png%') HOẶC (tên LIKE '% jpg%') HOẶC (tên LIKE '% bmp%') THÌ 'Hình ảnh' KHI (tên LIKE '% txt%') THÌ 'Tệp văn bản' Khi nào (tên LIKE '% xls%') THÌ 'Tệp văn bản' Khi (tên LIKE '% doc%') THÌ 'Tệp văn bản' ELSE 'Tệp khác' KẾT THÚC NHƯ 'Loại tệp' TỪ Document_List nơi name =@FileName) SET @SQLText ='Chèn vào Document_Content (ID, RootDirectory, FileName, FileAttribute, FileCreateDate, FileSize, FileType, FileStreamCol) Chọn NEWID (),' '' + @FileLocation + '' ',' '' + @FileName + '' ',' '' + @FileAttribute + '' ',' '' + @FileCreateDate + '' ',' '' + @FileSize + '' ',' '' + @FileType + '', số lượng lớn từ Openrowset (Bulk '' '+ @FileLocation +' '', Single_Blob) dưới dạng tb 'EXEC Sp_executesql @SQLText XÓA TỪ Document_List WHERE name =@FileName SET @I =@I + 1END 

Bước 4:Gói toàn bộ mã SQL trong một quy trình được lưu trữ

Tạo thủ tục được lưu trữ được tham số hóa có tên sp_Insert_Files và bọc mã trong đó.

Mã của Thủ tục được Lưu trữ như sau:

 sử dụng Thủ tục FileStream_DemogoCreate sp_Insert_Files @ FileLoc varchar (max) as begin DECLARE @FileCount INTDECLARE @I INT =0DECLARE @FileName NVARCHAR (max) DECLARE @SQLText NVARCHAR (max) khai báo @PSScript varchar (2500) DECLARE ) khai báo @FileAttribute varchar (50) khai báo @FileCreateDate varchar (50) khai báo @FileSize varchar (10) khai báo @FileType varchar (20) set @ PSScript ='powershell.exe getFileList' '' + @FileLoc + '' '' thực thi xp_cmdshell @PSScriptSET @FileCount =(SELECT Count (*) FROM Document_List) WHILE (@i <@FileCount) BEGIN / * Lấy tên tệp từ bảng Document_Name * / SET @FileName =(CHỌN tên TOP 1 TỪ Document_List) / * Điền Chi tiết tệp từ bảng Document_List * / SET @FileName =(CHỌN ĐẦU 1 tên TỪ Document_List) SET @FileLocation =(CHỌN ĐẦU 1 tên đầy đủ TỪ Document_List trong đó tên =@FileName) SET @FileAt Tribute =(CHỌN HÀNG ĐẦU 1 thuộc tính TỪ Document_List trong đó name =@FileName) SET @FileCreateDate =(CHỌN TOP 1 CreationTime TỪ Document_List trong đó name =@FileName) SET @FileSize =(CHỌN TOP 1 Độ dài TỪ Document_List trong đó name =@FileName) / * Xác định loại tệp * / SET @FileType =(CHỌN HÀNG ĐẦU 1 TRƯỜNG HỢP KHI (tên LIKE '% jpg%') HOẶC (tên LIKE '% png%') HOẶC (tên LIKE '% jpg%') HOẶC (tên LIKE '% bmp%') THÌ 'Hình ảnh' KHI (tên LIKE '% txt%') THÌ 'Tệp văn bản' Khi (tên LIKE '% xls%') THÌ 'Tệp văn bản' Khi (tên LIKE '% doc%') SAU ĐÓ 'Tệp văn bản' ELSE 'Tệp khác' KẾT THÚC LÀ 'Loại tệp' TỪ Document_List where name =@FileName) SET @SQLText ='Chèn vào Document_Content (ID, RootDirectory, FileName, FileAtt ribute, FileCreateDate, FileSize, FileType, FileStreamCol) Chọn NEWID (), '' '+ @FileLocation +' '', '' '+ @FileName +' '', '' '+ @FileAttribute +' '', '' '+ @FileCreateDate +' '', '' '+ @FileSize +' '', '' '+ @FileType +' '', số lượng lớnColumn từ Openrowset (Bulk '' '+ @FileLocation +' '', Single_Blob) dưới dạng tb 'EXEC Sp_executesql @SQLText XÓA KHỎI Document_List WHERE name =@FileName SET @I =@I + 1ENDEnd 

Chèn tệp bằng thủ tục đã lưu trữ

Bây giờ hãy kiểm tra thủ tục được lưu trữ. Tôi đã thêm một vài tệp vào E:\ Files danh mục. Chèn các tệp vào bảng SQL bằng cách thực hiện quy trình đã lưu trữ. Mã như sau:

 sử dụng FileStream_Demogoexec sp_Insert_Files 'E:\ Files' 

Hãy xác minh rằng các tệp đã được sao chép vào bảng. Đối với điều này, hãy thực thi đoạn mã sau:

 chọn RootDirectory làm 'Vị trí tệp', Tên tệp là 'Tên tệp', FileAttribute làm "Thuộc tính", FileCreateDate làm "Thuộc tính", Kích thước tệp là "Kích thước tệp", FileType là "Loại tệp", FileStreamCol làm "Nội dung tệp" từ Document_Content nơi FileType ='Hình ảnh' 

Đầu ra của truy vấn như sau:

Để truy cập tệp trên kho dữ liệu FILESTREAM bằng Win32 API, hãy sử dụng Tên đường dẫn () phương pháp FILESTREAM. Với Tên đường dẫn () , chúng tôi có thể xác định đường dẫn hợp lý để phát hiện tệp trong kho lưu trữ dữ liệu FILESTREAM duy nhất.

Mã như sau:

 chọn RootDirectory làm 'Vị trí tệp', Tên tệp là "Tên tệp", FileAttribute làm "Thuộc tính", FileCreateDate làm "Thuộc tính", Kích thước tệp là "Kích thước tệp", FileType là "Loại tệp", FileStreamCol.PathName () AS FilePathfrom Document_Content nơi FileName ='RowDesign.png' 

Đầu ra của truy vấn như sau:

Hãy điều hướng đến vùng chứa dữ liệu FILESTREAM (E:\ Dummy-Documents) để xác minh rằng các tệp đã được chèn. Xem ảnh chụp màn hình sau:

Như bạn có thể thấy, tất cả các tệp đã được chèn vào bảng SQL và vùng chứa FileStream.

Tóm tắt

Trong bài viết này, tôi đã đề cập đến:

  1. Truy vấn hữu ích để xác minh các điều kiện tiên quyết của tính năng FILESTREAM.
  2. Cách đăng ký chức năng PowerShell dưới dạng mô-đun.
  3. Giải thích mã PowerShell để chèn danh sách tệp trong bảng SQL bằng tập lệnh PowerShell.
  4. Giải thích mã của thủ tục được lưu trữ để chèn nhiều Tệp trong Bảng SQL.
  5. Các truy vấn hữu ích để thu thập danh sách tài liệu, được lưu trữ trong vùng chứa FILESTREAM.

Trong các bài viết tới, tôi sẽ giải thích cách sao lưu và khôi phục cơ sở dữ liệu đã bật FILESTREAM.

Hãy theo dõi!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hướng dẫn triển khai TimescaleDB với Docker

  2. Mọi thứ bạn cần biết về SQL CTE tại một điểm

  3. SQL giữa toán tử

  4. Thay đổi cách isql thực thi SQL

  5. Hướng dẫn giao dịch SQL