Database
 sql >> база данни >  >> RDS >> Database

Съхранение на файлове в SQL база данни с помощта на FILESTREAM – част 2

В предишната си статия описах как да конфигурирате FILESTREAM в SQL Server, да създавате база данни и таблици с активиран FILESTREAM. Освен това демонстрирах как да вмъквам и изтривам данни от таблицата FILESTREAM.

В тази статия ще демонстрирам как да вмъкнете множество файлове в таблица FILESTREAM с помощта на T-SQL.

В тази демонстрация ще използваме модула PowerShell, за да попълним списъка с файлове и да го съхраняваме в SQL таблицата.

Необходими проверки и полезни заявки за получаване на конфигурации на FILESTREAM

За тази демонстрация използвам:

  1. Версия на SQL:SQL Server 2017
  2. База данни:FileStream_Demo база данни
  3. Инструменти:PowerShell, SQL Server Management Studio, SQL Server Data Tools.

В предишната си статия създадох база данни с име FileStream_Demo . Функцията FILESTREAM е активирана на екземпляр на SQL Server и базата данни има разрешение за ниво на достъп T-SQL и Win32.

За да прегледате настройките за ниво на достъп FILESTREAM, изпълнете следната заявка:

Използвайте FileStream_DemoGoSELECT Host_Name() като 'Име на сървър' ,NAME като 'Конфигурация на база данни', CASE WHEN стойност =0 THEN 'FILESTREAM е деактивиран' WHEN стойност =1 THEN 'Разрешено за T-SQL' WHEN стойност' =2 THEN Активирано за T-SQL и Win32' END AS 'FILESTREAM Option'FROM sys.configurationsWHERE NAME ='filestream access level'Go

Резултатът от заявката е както следва:

За да прегледате файловете на базата данни и местоположението на контейнера с данни FILESTREAM, изпълнете следната заявка:

Използвайте FileStream_DemoGoSELECT Host_Name() като „Име на сървъра“, NAME като „Име на файлова група“, type_desc като „Тип на файлова група“, физическо_name като „Местоположение на файла на базата данни“ FROM sys.database_files

Резултатът от заявката е както следва:

Вмъкване на множество файлове с помощта на SQL скрипт

За да вмъкнете няколко файла в SQL таблица:

  1. Създайте две SQL таблици с име Document_List и Document_Content . Document_Content таблицата съдържа FileStreamCol колона с типа данни VARBINARY(MAX) и атрибута на колоната FILESTREAM. Съдържанието на файловете в директорията ще се преобразува във VARBINARY(MAX) и ще се съхранява в FileStreamCol колона на Document_Content маса.
  2. Създайте динамична SQL заявка, която се повтаря през Document_Location таблица, за да получите пътя на файловете и да вмъкнете файлове в Document_Content таблици.
  3. Увийте целия T-SQL код в съхранена процедура.

Създаване на SQL таблици

Първо, създайте глобална временна таблица за съхраняване на подробностите за файловете. За това изпълнете следната заявка в FileStream_Demo база данни.

ИЗПОЛЗВАЙТЕ [FileStream_Demo]GOCreate таблица Document_List( ID int identity(1,1) Клъстериран първичен ключ, пълно име Varchar(max), име Varchar(max), атрибути Varchar(250), CreationTime datetime, LastAccessTime datetime, LastWriteTime datetime, Числова дължина (10,2))

Освен това създайте таблица за съхраняване на файловете в таблицата. Изпълнете следната заявка, за да създадете физическа таблица:

ИЗПОЛЗВАЙТЕ [FileStream_Demo]GOCREATE TABLE [dbo].[Document_Content ]( [ID] [уникален идентификатор] ROWGUIDCOL NOT NULL, [RootDirectory] [varchar](max) NULL, [FileName] [varchar](max) NULL, [Max) FileAttribute] [varchar](150) NULL, [FileCreateDate] [datetime] NULL, [FileSize] [числова](10, 5) NULL, [FileStreamCol] [varbinary](max) FILESTREAM NULL,UNIQUE NONCLUSTERED (UNIQUE NONCLUSTERED) )С (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ВКЛ. 

За да подобрите производителността на заявката за избор, добавете клъстериран индекс към Име на файл и FileType колони на Document_Content маса. За целта изпълнете следния код:

ИЗПОЛЗВАЙТЕ [FileStream_Demo]GOCREATE CLUSTERED INDEX [ICX_Document_Content_FileName] ВКЛЮЧЕНО [dbo].[Document_Content]( [FileName] ASC, [FileType] ASC)С (PAD_INDEX =OFF, STATISTISTICS_OFF_OFF, COMPUTSOMPDB OFF, COMPUSTISTICS_NORE_OFF, COMPUTSOMPDB_INEX, COMPUTER) ОНЛАЙН =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ., ALLOW_PAGE_LOCKS =ВКЛ.) НА [ОСНОВЕН] FILESTREAM_ON [Dummy-Documents]GO

Създайте модул PowerShell за попълване на подробности за файла

След като таблиците бъдат създадени, изпълнете скрипта PowerShell, за да вмъкнете подробности за файловете в Document_List маса. Скриптът PowerShell се изпълнява в рамките на съхранената процедура на T-SQL, следователно, за да напишете целия код в SQL процедурата, трябва да създадете функция PowerShell. Пътят на директорията е задължителен входен параметър на функцията. Скриптът получава списък с файлове, който се намира в параметъра на директорията, използван за изпълнение на функцията PowerShell.

Кодът е както следва:

  1. Създайте функция и декларирайте задължителни входни параметри. Кодът е както следва:
    function global:getFileList{param( [Parameter(Position=0,mandatory=$true)] [string[]] $FilePath)
  2. Създайте низ, който има заявка „Insert“. Вижте следния код:
    [email protected]'INSERT INTO ##Document_List( пълно име, име, атрибути, CreationTime, LastAccessTime, LastWriteTime, Length) VALUES ('{0}', '{1}', '{ 2}', '{3}', '{4}', '{5}', '{6}')'@
  3. Вземете списъка с файлове, като използвате командата Get-ChildItem -Recurse, форматирайте изхода на командата. Кодът е както следва:
    Get-ChildItem -Recurse $Directorypath | изберете @{Label="FullName";Expression={split-path($_.FullName)}}, име, атрибути, CreationTime, LastAccessTime, LastWriteTime,@{Label="Length";Expression={$_.Length / 1MB -като [int] }}
  4. Използвайки цикъла For-Each, запазете изхода в Document_content маса. За да стартирате заявката на FileStream_Demo база данни, скриптът използва Invoke-Sqlcmd . Кодът е както следва:
    ForEach-Object { $SQL =$sqltmplt -f $_.FullName, $_.name, $_.attributes, $_.CreationTime, $_.LastAccessTime, $_.LastWriteTime, $_.Length Invoke-sqlcmd -Query $SQL -ServerInstance TTI412-VM\SQL2017 -database FileStream_Demo }

Целият код на функцията PowerShell ще изглежда по следния начин:

function global:getFileList{param( [Parameter(Position=0,mandatory=$true)] [string[]] $FilePath)Write-Output "Inserting files"[email protected]'INSERT INTO dbo.Document_List( пълно име, име, атрибути, CreationTime, LastAccessTime, LastWriteTime, Length ) СТОЙНОСТИ ( '{0}', '{1}', '{2}', '{3}', '{4}', '{5} ', '{6}')'@Invoke-Sqlcmd -Запитване "Отрязване на таблица с документи_списък" -ServerInstance TTI412-VM\SQL2017 -database FileStream_DemoGet-ChildItem -Recurse $FilePath | изберете @{Label="FullName";Expression={split-path($_.FullName)}},name,attributes, CreationTime, LastAccessTime, LastWriteTime,@{Label="Length";Expression={$_.Length / 1MB -като [int] }}| ForEach-Object {$SQL =$sqltmplt -f $_.FullName, $_.name,$_.attributes, $_.CreationTime, $_.LastAccessTime, $_.LastWriteTime,$_.Length Invoke-sqlcmd -Query $SQL -ServerInstance TTI412-VM\SQL2017 -database FileStream_Demo}Write-Output "Файлът е вмъкнат успешно... По-долу има списък с файлове."}

За да използваме функцията PowerShell в рамките на SQL Stored процедура, трябва да регистрираме горния скрипт като PowerShell Module. За целта създайте директория с имеgetFileList в C:\Windows\System32\WindowsPowerShell\v1.0\Modules . За да регистрирате който и да е скрипт на PowerShell като модул, имената на скрипта и директориите трябва да са еднакви. Следователно запазете горния скрипт катоgetFileList.psm1 в getFileList директория.

Сега, когато изпълнихме скрипта PowerShell от T-SQL, трябва да импортираме getFileList модул. За това добавете следния код в профила на PowerShell. Профилът на PowerShell ще бъде създаден в C:\Windows\System32\WindowsPowerShell\v1.0 местоположение.

import-module getFileList

Ако профилът не съществува, изпълнете следната команда, за да създадете профил.

Нов елемент -Тип файл -Път $PROFILE.AllUsersAllHosts -Force

Създайте съхранена процедура за импортиране на файлове

След като съхраним списъка с файлове и информацията в SQL таблица, ще вмъкнем файловете в Document_Content таблица.

За да изпълните тази задача ефективно, създайте параметризирана съхранена процедура с име sp_Insert_Documents . Той ще използва FileLocation параметър, който е от типа данни varchar. Процедурата попълва списъка с файлове от местоположението, посочено в параметъра, и вмъква всички файлове в Document_Content таблица.

Стъпка 1:Променете конфигурационния параметър.

За да стартирате командата PowerShell с помощта на T-SQL, активирайте xp_cmdshell опция за конфигурация. Това е разширена опция за конфигурация; следователно преди да активирате xp_cmdshell , активирайте Показване на разширената опция опция за конфигурация. За това изпълнете последователно следните T-SQL команди.

използвайте mastergoexec sp_configure 'покажи разширена опция',1преконфигурирайте с overrideExec sp_configure 'xp_cmdshell',1преконфигурирайте с override

Стъпка 2:Използвайте скрипт на PowerShell, за да попълните списъка с файлове в T-SQL код

За да изпълните скрипт на PowerShell с помощта на T-SQL, използвайте xp_cmdshell процедура. Той изпълнява командата PowerShell, която попълва списък с файлове и техните подробности в Document_List таблица.
Кодът е както следва:

декларирайте @PSScript varchar(2500)set @PSScript='powershell.exe getFileList ''' + @FileLoc +'''' exec xp_cmdshell @PSScript

Стъпка 3:Създайте динамична SQL заявка, за да получите местоположението на файла

Създайте динамична SQL заявка, която минава през Document_List таблица, зарежда съдържанието на файла, намиращ се по пътя, посочен в Пълно име колона, преобразува я в колоната VARBINAR(MAX) и я вмъква в Document_Content маса. Заедно с File, скриптът вмъква име на файл, атрибут на файл, размер на файл и тип файл в Document_Content маса. Скриптът използва случая израз за определяне на типа на файла.

Кодът е както следва:

SET @FileCount =(SELECT Count(*) FROM Document_List) WHILE ( @i <@FileCount) BEGIN SET @FileName =(ИЗБЕРЕТЕ ТОП 1 име ОТ Document_List) /* Свържете колоната за местоположение на директория и име на файл, за да генерирате FQDN. */ SET @FileName =(ИЗБЕРЕТЕ ТОП 1 име ОТ Document_List) SET @FileLocation =(ИЗБЕРЕТЕ ТОП 1 пълно име ОТ Document_List, където име=@FileName) SET @FileAttribute =(SELECT TOP 1 атрибути ОТ Document_List, където име=@FileName) SET @ FileCreateDate =(ИЗБЕРЕТЕ TOP 1 CreationTime ОТ Document_List, където име=@FileName) SET @FileSize =(SELECT TOP 1 Length FROM Document_List, където име=@FileName) SET @FileType =(ИЗБЕРЕТЕ ТОП 1 СЛУЧАЙ, КОГАТО ( име КАТО '%jpg%' ) ИЛИ ( име КАТО '%png%' ) ИЛИ ( име КАТО '%jpg%' ) ИЛИ ( име КАТО '%bmp%' ) СЛЕД 'Изображения' КОГА ( име КАТО '%txt%' ) СЛЕД 'Текстови файлове' Когато ( име КАТО '%xls%' )СЛЕД 'Текстови файлове' Когато (име КАТО '%doc%' ) СЛЕД 'Текстови файлове' ОЩЕ 'Други файлове' END КАТО 'Тип на файл' FROM Document_List, където име=@FileName) SET @SQLText ='Вмъкване в Document_Content (ID, RootDirectory, FileName, FileAttribute,FileCreateDate,FileSize,FileType,FileStreamCol), ''Location'' Изберете NEWID @File(le) + ''', ''' + @FileName + ''', ''' + @FileAttribute + ''', ''' + @FileCreateDate + ''', ''' + @FileSize + ''', ' '' + @FileType + ''', bulkColumn от Openrowset(Bulk '''+ @FileLocation + ''', Single_Blob) като tb' EXEC Sp_executesql @SQLText DELETE FROM Document_List WHERE name =@FileName SET @I =@I + 1 КРАЙ

Стъпка 4:Увийте целия SQL код в съхранена процедура

Създайте параметризирана съхранена процедура с име sp_Insert_Files и увийте кода в него.

Кодът на съхранената процедура е както следва:

използвайте процедурата FileStream_DemogoCreate sp_Insert_Files@FileLoc varchar(max)като начало ДЕКЛАРИРАНЕ @FileCount INTDECLARE @I INT =0DECLARE @FileName NVARCHAR(max)DECLARE @SQLText NVARCHAR(max)LoPS2DECLARE @SQLText NVARCHAR(max). )declare @FileAttribute varchar(50)declare @FileCreateDate varchar(50)declare @FileSize varchar(10)declare @FileType varchar(20)set @PSScript='powershell.exe getFileList ''' + @FileLoc +'' xp_cmdshell @PSScriptSET @FileCount =(SELECT Count(*) FROM Document_List) WHILE ( @i <@FileCount ) BEGIN /* Вземете името на файла от таблицата Document_Name */ SET @FileName =(SELECT TOP 1 name FROM Document_List) /* Попълване Подробности за файла от таблицата Document_List*/ SET @FileName =(SELECT TOP 1 Name FROM Document_List) SET @FileLocation =(SELECT TOP 1 fullname FROM Document_List, където име=@FileName) SET @FileAt tribute =(ИЗБЕРЕТЕ ТОП 1 атрибути ОТ Document_List, където име=@FileName) SET @FileCreateDate =(SELECT TOP 1 CreationTime FROM Document_List, където име=@FileName) SET @FileSize =(ИЗБЕРЕТЕ TOP 1 дължина ОТ Document_List, където име=@FileName) *Определете типа на файла*/ SET @FileType =(ИЗБЕРЕТЕ ТОП 1 СЛУЧАЙ КОГАТО ( име КАТО '%jpg%' ) ИЛИ ( име КАТО '%png%' ) ИЛИ ( име КАТО '%jpg%' ) ИЛИ ( име КАТО '%bmp%' ) СЛЕД 'Изображения' КОГА (име КАТО '%txt%' )СЛЕД 'Текстови файлове' Когато (име КАТО '%xls%' )СЛЕД 'Текстови файлове' Когато (име КАТО '%doc%') СЛЕД 'Текстови файлове' ДРУГИ 'Други файлове' КРАЙ КАТО 'Тип на файл' ОТ Document_List, където име=@FileName) SET @SQLText ='Вмъкване в Document_Content (ID, RootDirectory, FileName, FileAtt ribute,FileCreateDate,FileSize,FileType,FileStreamCol) Изберете NEWID(), ''' + @FileLocation + ''', ''' + @FileName + ''', ''' + @FileAttribute + ''', '' ' + @FileCreateDate + ''', ''' + @FileSize + ''', ''' + @FileType + ''', bulkColumn от Openrowset(Bulk '''+ @FileLocation + ''', Single_Blob) като tb' EXEC Sp_executesql @SQLText DELETE FROM Document_List WHERE име =@FileName SET @I =@I + 1ENDEnd

Вмъкване на файлове с помощта на съхранена процедура

Сега тествайте съхранената процедура. Добавих няколко файла към E:\Files директория. Вмъкнете файловете в SQL таблицата, като изпълните съхранената процедура. Кодът е както следва:

използвайте FileStream_Demogoexec sp_Insert_Files 'E:\Files'

Нека проверим дали файловете са копирани в таблицата. За целта изпълнете следния код:

изберете RootDirectory като „Местоположение на файла“, FileName като „Име на файл“, FileAttribute като „Attribute“, FileCreateDate като „Attribute“, FileSize като „File Size“, FileType като „File Type“, FileStreamCol като „File Content“ от Document_Content, където FileType='Images'

Резултатът от заявката е както следва:

За достъп до файла в хранилището за данни FILESTREAM с помощта на Win32 API, използвайте Име на пътя () метод на FILESTREAM. Симе на пътя () метод, можем да идентифицираме логическия път за откриване на файла в хранилището на данни FILESTREAM уникално.

Кодът е както следва:

изберете RootDirectory като „Местоположение на файла“, FileName като „Име на файл“, FileAttribute като „Attribute“, FileCreateDate като „Attribute“, FileSize като „File Size“, FileType като „File Type“, FileStreamCol.PathName() AS. FilePathfrom Document_Content, където FileName='RowDesign.png'

Резултатът от заявката е както следва:

Нека отидем до контейнера с данни FILESTREAM (E:\Dummy-Documents), за да проверим дали файловете са били вмъкнати. Вижте следната екранна снимка:

Както можете да видите, всички файлове са били вмъкнати в SQL таблици и в контейнера FileStream.

Резюме

В тази статия разгледах:

  1. Полезна заявка за проверка на предпоставките за функцията FILESTREAM.
  2. Как да регистрирам функция PowerShell като модул.
  3. Обяснете кода на PowerShell за вмъкване на списък с файлове в SQL таблица с помощта на PowerShell скрипт.
  4. Обясни кода на съхранената процедура за вмъкване на множество файлове в SQL таблица.
  5. Полезни заявки за събиране на списък с документи, съхранявани в контейнер FILESTREAM.

В бъдещи статии ще обясня как да архивирам и възстановя базата данни с активиран FILESTREAM.

Останете на линия!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Помощна програма за проверка на клъстер, генерираща голям брой xml файлове във файловата система “/u01”.

  2. Как да преименувате име на колона в SQL?

  3. Използване на псевдоколони с свързан сървър

  4. Внедряване на приложение Django в AWS Elastic Beanstalk

  5. Как да изчислим общия брой на бягане в червено изместване