Database
 sql >> Baza danych >  >> RDS >> Database

Przechowywanie plików w bazie danych SQL przy użyciu FILESTREAM — część 2

W moim poprzednim artykule opisałem, jak skonfigurować FILESTREAM w SQL Server, utworzyć bazę danych i tabele obsługujące FILESTREAM. Ponadto zademonstrowałem, jak wstawiać i usuwać dane z tabeli FILESTREAM.

W tym artykule pokażę, jak wstawić wiele plików do tabeli FILESTREAM za pomocą T-SQL.

W tym demo użyjemy modułu PowerShell do wypełnienia listy plików i przechowywania jej w tabeli SQL.

Kontrole wymagań wstępnych i przydatne zapytania w celu uzyskania konfiguracji FILESTREAM

Do tego demo używam:

  1. Wersja SQL:SQL Server 2017
  2. Baza danych:FileStream_Demo baza danych
  3. Narzędzia:PowerShell, SQL Server Management Studio, SQL Server Data Tools.

W poprzednim artykule stworzyłem bazę danych o nazwie FileStream_Demo . Funkcja FILESTREAM jest włączona w instancji SQL Server, a baza danych ma uprawnienia poziomu dostępu T-SQL i Win32.

Aby przejrzeć ustawienia poziomu dostępu FILESTREAM, wykonaj następujące zapytanie:

Użyj FileStream_DemoGoSELECT Host_Name() jako „Nazwa serwera”, NAME jako „Konfiguracja bazy danych”, CASE WHEN =0 THEN „FILESTREAM jest wyłączony” WHEN wartość =1 THEN „Włączone dla T-SQL” WHEN wartość =2 THEN „ Włączone dla T-SQL i Win32' END AS 'FILESTREAM Option'FROM sys.configurationWHERE NAME ='poziom dostępu do strumienia plików'Go

Wynik zapytania jest następujący:

Aby przejrzeć pliki bazy danych i lokalizację kontenera danych FILESTREAM, wykonaj następujące zapytanie:

Użyj FileStream_DemoGoSELECT Host_Name() jako „Nazwa serwera”, NAME jako „Nazwa grupy plików”, type_desc jako „Typ grupy plików”, Physical_name jako „Lokalizacja pliku bazy danych” FROM sys.database_files

Wynik zapytania jest następujący:

Wstaw wiele plików za pomocą skryptu SQL

Aby wstawić wiele plików do tabeli SQL:

  1. Utwórz dwie tabele SQL o nazwie Document_List i Document_Content . Treść_dokumentu tabela zawiera FileStreamCol kolumna z typem danych VARBINARY(MAX) i atrybutem kolumny FILESTREAM. Zawartość plików w katalogu zostanie przekonwertowana w VARBINARY(MAX) i przechowywana w FileStreamCol kolumna Document_Content stół.
  2. Utwórz dynamiczne zapytanie SQL, które przechodzi przez Położenie_dokumentu tabeli, aby uzyskać ścieżkę plików i wstawić pliki w Document_Content stoły.
  3. Opakuj cały kod T-SQL w procedurę składowaną.

Utwórz tabele SQL

Najpierw utwórz globalną tabelę tymczasową do przechowywania szczegółów plików. W tym celu wykonaj następujące zapytanie w FileStream_Demo baza danych.

UŻYJ [FileStream_Demo]GOCreate tabeli Document_List(ID int identity(1,1) Klucz podstawowy w klastrze, pełna nazwa Varchar(max), nazwa Varchar(max), atrybuty Varchar(250), CreationTime datetime, LastAccessTime datetime, LastWriteTime datetime, Numeryczna długość(10,2))

Ponadto utwórz tabelę do przechowywania plików w tabeli. Wykonaj następujące zapytanie, aby utworzyć fizyczną tabelę:

 USE [FileStream_Demo] GOCREATE TABLE [dbo]. [Document_Content] ( [ID] [unikalny identyfikator] ROWGUIDCOL NIE NULL, [RootDirectory] [varchar] (maks.) NULL, [FileName] [varchar] (maks.) NULL, [ FileAttribute] [varchar](150) NULL, [FileCreateDate] [datetime] NULL, [FileSize] [numeric](10, 5) NULL, [FileStreamCol] [varbinary](max) FILESTREAM NULL,UNIKALNE NIECLUSTROWANE ([ID] ASC )Z (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-PreDocuments 

Aby poprawić wydajność zapytania wybierającego, dodaj indeks klastrowy w Nazwie pliku i Typ pliku kolumny Document_Content stół. W tym celu wykonaj następujący kod:

UŻYJ [FileStream_Demo]GOCREATE SKLASTROWANY INDEKS [ICX_Document_Content_FileName] ON [dbo].[Document_Content]( [FileName] ASC, [FileType] ASC)WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, DROP_EXING_IN_TE ONLINE =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY] FILESTREAM_ON [Dummy-Documents] GO

Utwórz moduł PowerShell, aby wypełnić szczegóły pliku

Po utworzeniu tabel uruchom skrypt PowerShell, aby wstawić szczegóły plików w Document_List stół. Skrypt PowerShell działa w ramach procedury składowanej T-SQL, dlatego aby napisać cały kod w procedurze SQL, należy utworzyć funkcję PowerShell. Ścieżka do katalogu jest obowiązkowym parametrem wejściowym funkcji. Skrypt pobiera listę plików, znajduje się w parametrze directory używanym do wykonania funkcji PowerShell.

Kod wygląda następująco:

  1. Utwórz funkcję i zadeklaruj obowiązkowe parametry wejściowe. Kod wygląda następująco:
    function global:getFileList{param( [Parameter(Position=0,mandatory=$true)] [string[]] $FilePath)
  2. Zbuduj ciąg, który zawiera zapytanie „Wstaw”. Zobacz następujący kod:
    [email protected]'INSERT INTO ##Document_List( imię i nazwisko, atrybuty, CreationTime, LastAccessTime, LastWriteTime, Length) VALUES ( '{0}', '{1}', '{ 2}', '{3}', '{4}', '{5}', '{6}')'@
  3. Pobierz listę plików za pomocą polecenia Get-ChildItem -Recurse sformatuj dane wyjściowe polecenia. Kod wygląda następująco:
    Get-ChildItem -Recurse $Directorypath | wybierz @{Label="FullName";Expression={split-path($_.FullName)}}, nazwa, atrybuty, CreationTime, LastAccessTime, LastWriteTime,@{Label="Length";Expression={$_.Length / 1MB -jako [int] }}
  4. Korzystając z pętli For-Each, zapisz dane wyjściowe w Document_content stół. Aby uruchomić zapytanie w FileStream_Demo bazy danych, skrypt używa Invoke-Sqlcmd . Kod wygląda następująco:
    ForEach-Object { $SQL =$sqltmplt -f $_.FullName, $_.name, $_.attributes, $_.CreationTime, $_.LastAccessTime, $_.LastWriteTime, $_.Length Invoke-sqlcmd -Query $SQL -ServerInstance TTI412-VM\SQL2017 -database FileStream_Demo }

Cały kod funkcji PowerShell będzie wyglądał następująco:

function global:getFileList{param( [Parameter(Position=0,mandatory=$true)] [string[]] $FilePath)Write-Output "Wstawianie plików"[email protected]'INSERT INTO dbo.Document_List( imię i nazwisko, nazwa, atrybuty, CreationTime, LastAccessTime, LastWriteTime, Length ) WARTOŚCI ( „{0}”, „{1}”, „{2}”, „{3}”, „{4}”, „{5} ', '{6}')'@Invoke-Sqlcmd -Query "Truncate Table Document_List" -ServerInstance TTI412-VM\SQL2017 -database FileStream_DemoGet-ChildItem -Recurse $FilePath | wybierz @{Label="FullName";Expression={split-path($_.FullName)}},name,attributes, CreationTime, LastAccessTime, LastWriteTime,@{Label="Length";Expression={$_.Length / 1MB -jako [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 "Plik wstawiono pomyślnie... Poniżej znajduje się lista plików."}

Aby skorzystać z funkcji PowerShell w ramach procedury składowanej SQL, musimy zarejestrować powyższy skrypt jako moduł PowerShell. W tym celu utwórz katalog o nazwie getFileList w C:\Windows\System32\WindowsPowerShell\v1.0\Moduły . Aby zarejestrować dowolny skrypt PowerShell jako moduł, nazwy skryptów i katalogów powinny być takie same. Dlatego zapisz powyższy skrypt jako getFileList.psm1 w getFileList katalog.

Teraz, gdy wykonaliśmy skrypt PowerShell z T-SQL, musimy zaimportować getFileList moduł. W tym celu dodaj następujący kod w profilu PowerShell. Profil PowerShell zostanie utworzony w C:\Windows\System32\WindowsPowerShell\v1.0 lokalizacja.

import-moduł getFileList

Jeśli profil nie istnieje, wykonaj następujące polecenie, aby utworzyć profil.

Nowa pozycja -Type File -Path $PROFILE.AllUsersAllHosts -Force

Utwórz zapisaną procedurę importowania plików

Po zapisaniu listy plików i informacji w tabeli SQL wstawimy pliki do Document_Content tabela.

Aby skutecznie wykonać to zadanie, utwórz sparametryzowaną procedurę składowaną o nazwie sp_Insert_Documents . Użyje Lokalizacja pliku parametr, który jest typu danych varchar. Procedura wypełnia listę plików z lokalizacji podanej w parametrze i wstawia wszystkie pliki w Document_Content tabela.

Krok 1:Zmień parametr konfiguracji.

Aby uruchomić polecenie PowerShell przy użyciu T-SQL, włącz xp_cmdshell opcja konfiguracji. Jest to zaawansowana opcja konfiguracji; stąd przed włączeniem xp_cmdshell , włącz Pokaż opcję zaawansowaną opcja konfiguracji. W tym celu wykonaj kolejno następujące polecenia T-SQL.

użyj mastergoexec sp_configure 'pokaż opcję zaawansowaną',1zmień konfigurację z overrideExec sp_configure 'xp_cmdshell',1zmień konfigurację z zastąpieniem

Krok 2:Użyj skryptu PowerShell, aby wypełnić listę plików w kodzie T-SQL

Aby wykonać skrypt PowerShell przy użyciu T-SQL, użyj xp_cmdshell procedura. Wykonuje polecenie PowerShell, które wypełnia listę plików i ich szczegóły w Lista_dokumentów tabeli.
Kod wygląda następująco:

declare @PSScript varchar(2500)set @PSScript='powershell.exe getFileList ''' + @FileLoc +'''' exec xp_cmdshell @PSScript

Krok 3:utwórz dynamiczne zapytanie SQL, aby uzyskać lokalizację pliku

Utwórz dynamiczne zapytanie SQL, które przechodzi przez Listę_dokumentów tabeli, ładuje zawartość pliku znajdującego się w ścieżce podanej w FullName kolumna, konwertuje ją na kolumnę VARBINAR(MAX) i wstawia do Document_Content stół. Wraz z plikiem skrypt wstawia nazwę pliku, atrybut pliku, rozmiar pliku i typ pliku do Document_Content stół. Skrypt wykorzystuje przypadek wyrażenie do określenia typu pliku.

Kod wygląda następująco:

SET @FileCount =(SELECT Count(*) FROM Document_List) WHILE ( @i <@FileCount ) BEGIN SET @FileName =(SELECT TOP 1 name FROM Document_List) /* Połącz kolumny DirectoryLocation i FileName, aby wygenerować FQDN. */ SET @FileName =(SELECT TOP 1 Name FROM Document_List) SET @FileLocation =(SELECT TOP 1 fullname FROM Document_List gdzie name=@FileName) SET @FileAttribute =(SELECT TOP 1 atrybuty FROM Document_List gdzie name=@FileName) SET @ FileCreateDate =(SELECT TOP 1 CreationTime FROM Document_List gdzie name=@FileName) SET @FileSize =(SELECT TOP 1 Length FROM Document_List gdzie name=@FileName) SET @FileType =(SELECT TOP 1 CASE WHEN ( nazwa LIKE '%jpg%' ) OR ( nazwa LIKE '%png%' ) OR ( nazwa LIKE '%jpg%' ) OR ( nazwa LIKE '%bmp%' ) THEN 'Obrazy' WHEN ( nazwa LIKE '%txt%' )THEN 'Pliki tekstowe' Kiedy ( nazwa LIKE '%xls%' )THEN 'Pliki tekstowe' Kiedy ( nazwa LIKE '%doc%' ) THEN 'Pliki tekstowe' ELSE 'Inne pliki' END AS 'Typ pliku' FROM Document_List gdzie name=@FileName) SET @SQLText ='Wstaw do Document_Content (ID, RootDirectory, FileName, FileAttribute,FileCreateDate,FileSize,FileType,FileStreamCol) Wybierz NEWID(), ''' + @FileLocation + ''', ''' + @FileName + ''', ''' + @FileAttribute + ''', ''' + @FileCreateDate + ''', ''' + @FileSize + ''', ' '' + @FileType + ''', bulkColumn z Openrowset(Bulk '''+ @FileLocation + ''', Single_Blob) as tb' EXEC Sp_executesql @SQLText DELETE FROM Document_List WHERE name =@FileName SET @I =@I + 1END

Krok 4:Umieść cały kod SQL w procedurze składowanej

Utwórz sparametryzowaną procedurę składowaną o nazwie sp_Insert_Files i zapakuj w nią kod.

Kod procedury składowanej jest następujący:

użyj procedury FileStream_DemogoCreate sp_Insert_Files@FileLoc varchar(max) jako początek DECLARE @FileCount INTDECLARE @I INT =0DECLARE @FileName NVARCHAR(max)DECLARE @SQLText NVARCHAR(max)declare @PSScript varchar(2500)DECLARE @PSScript varchar(2500)DECLARE )declare @FileAttribute varchar(50)declare @FileCreateDate varchar(50)declare @FileSize varchar(10)declare @FileType varchar(20)set @PSScript='powershell.exe getFileList ''' + @FileLoc +'''' exec xp_cmdshell @PSScriptSET @FileCount =(SELECT Count(*) FROM Document_List) WHILE ( @i <@FileCount ) BEGIN /* Pobierz nazwę pliku z tabeli Document_Name */ SET @FileName =(SELECT TOP 1 name FROM Document_List) /* Wypełnij Szczegóły pliku z tabeli Lista_dokumentów*/ SET @FileName =(WYBIERZ NAZWA TOP 1 FROM Lista_Dokumentów) SET @FileLocation =(WYBIERZ NAZWĘ TOP 1 FROM Lista_Dokumentów gdzie nazwa=@NazwaPliku) SET @FileAt tribute =(SELECT TOP 1 atrybuty FROM Document_List gdzie name=@FileName) SET @FileCreateDate =(SELECT TOP 1 CreationTime FROM Document_List gdzie name=@FileName) SET @FileSize =(SELECT TOP 1 Length FROM Document_List gdzie name=@FileName) / *Określ typ pliku*/ SET @FileType =(SELECT TOP 1 CASE WHEN ( nazwa LIKE '%jpg%' ) OR ( nazwa LIKE '%png%' ) OR ( nazwa LIKE '%jpg%' ) OR ( nazwa LIKE '%bmp%' ) THEN 'Obrazy' WHEN ( nazwa LIKE '%txt%' )THEN 'Pliki tekstowe' Kiedy ( nazwa LIKE '%xls%' )THEN 'Pliki tekstowe' Kiedy ( nazwa LIKE '%doc%' ) THEN 'Pliki tekstowe' ELSE 'Inne pliki' END AS 'Typ pliku' FROM Document_List gdzie name=@FileName) SET @SQLText ='Insert into Document_Content (ID, RootDirectory, FileName, FileAtt ribute,FileCreateDate,FileSize,FileType,FileStreamCol) Wybierz NEWID(), ''' + @FileLocation + ''', ''' + @FileName + ''', ''' + @FileAttribute + ''', '' ' + @FileCreateDate + ''', ''' + @FileSize + ''', ''' + @FileType + ''', bulkColumn z Openrowset(Bulk '''+ @FileLocation + ''', Single_Blob) jako tb' EXEC Sp_executesql @SQLText DELETE FROM Document_List WHERE name =@FileName SET @I =@I + 1ENDEnd

Wstaw pliki za pomocą procedury przechowywanej

Teraz przetestuj procedurę składowaną. Dodałem kilka plików do E:\Files informator. Wstaw pliki do tabeli SQL, wykonując procedurę składowaną. Kod wygląda następująco:

użyj FileStream_Demogoexec sp_Insert_Files 'E:\Files'

Sprawdźmy, czy pliki zostały skopiowane do tabeli. W tym celu wykonaj następujący kod:

 wybierz RootDirectory jako „Lokalizacja pliku”, FileName jako „Nazwa pliku”, FileAttribute jako „Atrybut”, FileCreateDate jako „Atrybut”, FileSize jako „Rozmiar pliku”, FileType jako „Typ pliku”, FileStreamCol jako „Zawartość pliku” z Document_Content, gdzie FileType='Obrazy'

Wynik zapytania jest następujący:

Aby uzyskać dostęp do pliku w magazynie danych FILESTREAM za pomocą interfejsu API Win32, użyj Pathname () metoda FILESTREAM. Z Nazwą ścieżki () metody, możemy zidentyfikować logiczną ścieżkę, aby jednoznacznie wykryć plik w magazynie danych FILESTREAM.

Kod wygląda następująco:

 wybierz RootDirectory jako „Lokalizacja pliku”, FileName jako „Nazwa pliku”, FileAttribute jako „Atrybut”, FileCreateDate jako „Atrybut”, FileSize jako „Rozmiar pliku”, FileType jako „Typ pliku”, FileStreamCol.PathName() AS FilePathfrom Document_Content gdzie FileName='RowDesign.png'

Wynik zapytania jest następujący:

Przejdźmy do kontenera danych FILESTREAM (E:\Dummy-Documents), aby sprawdzić, czy pliki zostały wstawione. Zobacz następujący zrzut ekranu:

Jak widać, wszystkie pliki zostały wstawione do tabel SQL i kontenera FileStream.

Podsumowanie

W tym artykule omówiłem:

  1. Przydatne zapytanie do weryfikacji wymagań wstępnych funkcji FILESTREAM.
  2. Jak zarejestrować funkcję PowerShell jako moduł.
  3. Wyjaśnij kod PowerShell, aby wstawić listę plików do tabeli SQL za pomocą skryptu PowerShell.
  4. Wyjaśniono kod procedury składowanej do wstawiania wielu plików do tabeli SQL.
  5. Przydatne zapytania do zebrania listy dokumentów przechowywanych w kontenerze FILESTREAM.

W przyszłych artykułach wyjaśnię, jak wykonać kopię zapasową i przywrócić bazę danych z obsługą FILESTREAM.

Bądź na bieżąco!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jakich umiejętności i wiedzy potrzebują projektanci baz danych?

  2. Łączenie F# z Salesforce.com

  3. Tworzenie nowych tabel w IRI Workbench

  4. Dołącz do 3 tabel w SQL

  5. Poprawa rozwiązania mediany górnej/górnej opadającej