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:
- Wersja SQL:SQL Server 2017
- Baza danych:FileStream_Demo baza danych
- 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:
- 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ół.
- 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.
- 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-PreDocumentsAby 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] GOUtwó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:
- 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)- 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}')'@- 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] }}- 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ł getFileListJeśli profil nie istnieje, wykonaj następujące polecenie, aby utworzyć profil.
Nowa pozycja -Type File -Path $PROFILE.AllUsersAllHosts -ForceUtwó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ąpieniemKrok 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 @PSScriptKrok 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 + 1ENDKrok 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 + 1ENDEndWstaw 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:
- Przydatne zapytanie do weryfikacji wymagań wstępnych funkcji FILESTREAM.
- Jak zarejestrować funkcję PowerShell jako moduł.
- Wyjaśnij kod PowerShell, aby wstawić listę plików do tabeli SQL za pomocą skryptu PowerShell.
- Wyjaśniono kod procedury składowanej do wstawiania wielu plików do tabeli SQL.
- 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!