sql >> Databáze >  >> RDS >> Database

Ukládání souborů do SQL databáze pomocí FILESTREAM – část 2

V mém předchozím článku jsem popsal, jak nakonfigurovat FILESTREAM v SQL Server, vytvořit databázi a tabulky podporující FILESTREAM. Navíc jsem předvedl, jak vkládat a mazat data z tabulky FILESTREAM.

V tomto článku ukážu, jak vložit více souborů do tabulky FILESTREAM pomocí T-SQL.

V této ukázce použijeme modul PowerShell k naplnění seznamu souborů a jeho uložení do tabulky SQL.

Nezbytné kontroly a užitečné dotazy pro získání konfigurací FILESTREAM

Pro toto demo používám:

  1. Verze SQL:SQL Server 2017
  2. Databáze:FileStream_Demo databáze
  3. Nástroje:PowerShell, SQL Server Management Studio, SQL Server Data Tools.

V předchozím článku jsem vytvořil databázi s názvem FileStream_Demo . Funkce FILESTREAM je povolena na instanci SQL Server a databáze má oprávnění úrovně přístupu T-SQL a Win32.

Chcete-li zkontrolovat nastavení úrovně přístupu FILESTREAM, proveďte následující dotaz:

Použijte FileStream_DemoGoSELECT Host_Name() jako 'Název serveru' ,NAME jako 'Konfiguraci databáze', CASE, KDYŽ hodnota =0 POTOM 'FILESTREAM je zakázán', KDYŽ hodnota =1 POTOM 'Povoleno pro T-SQL' KDYŽ hodnota =2 POTOM ' Povoleno pro T-SQL a Win32' KONČÍ JAKO 'FILESTREAM Option'FROM sys.configurationsWHERE NAME ='filestream access level'Go

Výstup dotazu je následující:

Chcete-li zkontrolovat databázové soubory a umístění datového kontejneru FILESTREAM, proveďte následující dotaz:

Použijte FileStream_DemoGoSELECT Host_Name() jako 'Server Name', NAME jako 'Filegroup Name', type_desc jako 'Filegroup Type', Physical_name jako 'Umístění databázového souboru' Z sys.database_files

Výstup dotazu je následující:

Vložit více souborů pomocí skriptu SQL

Chcete-li vložit více souborů do tabulky SQL:

  1. Vytvořte dvě tabulky SQL s názvem Document_List a Document_Content . Document_Content tabulka má FileStreamCol sloupec s datovým typem VARBINARY(MAX) a atributem sloupce FILESTREAM. Obsah souborů v adresáři bude převeden na VARBINARY(MAX) a uložen do FileStreamCol ve sloupci Document_Content stůl.
  2. Vytvořte dynamický dotaz SQL, který bude iterován přes Document_Location tabulky, abyste získali cestu k souborům a vložili soubory do Document_Content tabulky.
  3. Zabalte celý kód T-SQL do uložené procedury.

Vytvoření tabulek SQL

Nejprve vytvořte globální dočasnou tabulku pro uložení podrobností o souborech. Za tímto účelem spusťte následující dotaz v FileStream_Demo databáze.

USE [FileStream_Demo]GOCreate tabulku Document_List( ID int identity(1,1) Primární klíč seskupený, celé jméno Varchar(max), jméno Varchar(max), atributy Varchar(250), CreationTime datetime, LastAccessTime datetime, LastWriteTime datetime, Délka numeric(10,2))

Kromě toho vytvořte tabulku pro ukládání souborů do tabulky. Provedením následujícího dotazu vytvořte fyzickou tabulku:

POUŽÍVEJTE [FileStream_Demo]GOCREATE TABLE [dbo].[Document_Content ]( [ID] [jednoznačný identifikátor] 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 NENCLUSTERED ([ID] ASC )WITH (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMÁRNÍ]) NA [PRIMARY] TEXTIMAGE_ON [PRIMARY_umDoDocuments] [PRIMARY] [PRIMARY] [Cuments] 

Chcete-li zlepšit výkon výběrového dotazu, přidejte do Název souboru seskupený index a Typ souboru sloupce Document_Content stůl. Za tímto účelem spusťte následující kód:

POUŽÍVEJTE [FileStream_Demo]GOCREATE CLUSTERED INDEX [ICX_Document_Content_FileName] NA [dbo].[Document_Content]( [FileName] ASC, [FileType] ASC)S (PAD_INDEX =VYPNUTO, STATISTICS_NORETEDRTEMP =OPBISTING_OFF =EXBISTING_COMPUTE =OPB ONLINE =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY] FILESTREAM_ON [Dummy-Documents]GO

Vytvořte modul PowerShell pro vyplnění podrobností souboru

Po vytvoření tabulek spusťte skript PowerShell a vložte podrobnosti o souborech do Document_List stůl. Skript PowerShell běží v rámci uložené procedury T-SQL, a proto k zápisu celého kódu do procedury SQL musíte vytvořit funkci PowerShell. Cesta k adresáři je povinným vstupním parametrem funkce. Skript získá seznam souborů a je umístěn v parametru adresáře, který se používá ke spuštění funkce PowerShell.

Kód je následující:

  1. Vytvořte funkci a deklarujte povinné vstupní parametry. Kód je následující:
    function global:getFileList{param( [Parameter(Position=0,mandatory=$true)] [string[]] $FilePath)
  2. Vytvořte řetězec, který obsahuje dotaz „Insert“. Viz následující kód:
    [email protected]'INSERT INTO ##Document_List( celé jméno, jméno, atributy, CreationTime, LastAccessTime, LastWriteTime, Length) VALUES ( '{0}', '{1}', '{ 2}', '{3}', '{4}', '{5}', '{6}')'@
  3. Získejte seznam souborů pomocí příkazu Get-ChildItem -Recurse naformátujte výstup příkazu. Kód je následující:
    Get-ChildItem -Recurse $Directorypath | vyberte @{Label="CeléJméno";Výraz={split-path($_.FullName)}}, název, atributy, Čas vytvoření, Čas posledního přístupu, Čas posledního zápisu,@{Label="Délka";Výraz={$_.Length / 1 MB -as [int] }}
  4. Pomocí smyčky For-Each uložte výstup do Document_content stůl. Chcete-li spustit dotaz na FileStream_Demo databáze, skript používá Invoke-Sqlcmd . Kód je následující:
    ForEach-Object { $SQL =$sqltmplt -f $_.FullName, $_.name, $_.attributes, $_.CreationTime, $_.LastAccessTime, $_.LastWriteTime, $_.Length Invoke-sqlcmd -Dotaz $SQL -ServerInstance TTI412-VM\SQL2017 -databáze FileStream_Demo }

Celý kód funkce PowerShell bude vypadat takto:

funkce global:getFileList{param( [Parameter(Position=0,mandatory=$true)] [string[]] $FilePath)Write-Output "Vkládání souborů"[email protected]'INSERT INTO dbo.Document_List( celé jméno, jméno, atributy, CreationTime, LastAccessTime, LastWriteTime, Length ) VALUES ( '{0}', '{1}', '{2}', '{3}', '{4}', '{5} ', '{6}')'@Invoke-Sqlcmd -Dotaz "Zkrátit tabulku Document_List" -ServerInstance TTI412-VM\SQL2017 -databáze FileStream_DemoGet-ChildItem -Recurse $FilePath | vyberte @{Label="CeléJméno";Výraz={rozdělená-cesta($_.FullName)}},název,atributy,Čas vytvoření,Čas posledníhoPřístupu,Čas posledníhoZápisu,@{Label="Délka";Výraz={$_.Length / 1 MB -as [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 "Soubor úspěšně vložen... Níže je seznam souborů."}

Chcete-li použít funkci PowerShell v rámci SQL Stored procedury, musíme výše uvedený skript zaregistrovat jako PowerShell Module. Za tímto účelem vytvořte adresář s názvemgetFileList na C:\Windows\System32\WindowsPowerShell\v1.0\Modules . Chcete-li zaregistrovat jakýkoli skript PowerShell jako modul, názvy skriptu a adresáře by měly být stejné. Uložte tedy výše uvedený skript jakogetFileList.psm1 v getFileList adresář.

Nyní, když jsme spustili skript PowerShell z T-SQL, musíme importovat getFileList modul. Za tímto účelem přidejte do profilu PowerShell následující kód. Profil PowerShell bude vytvořen v C:\Windows\System32\WindowsPowerShell\v1.0 umístění.

import-module getFileList

Pokud profil neexistuje, vytvořte profil provedením následujícího příkazu.

Nová položka -Typ souboru -Cesta $PROFILE.AllUsersAllHosts -Force

Vytvořte uloženou proceduru pro import souborů

Jakmile uložíme seznam souborů a informace do tabulky SQL, vložíme soubory do Document_Content tabulka.

Chcete-li tento úkol provést efektivně, vytvořte parametrizovanou uloženou proceduru s názvemsp_Insert_Documents . Použije Umístění souboru parametr, který je datového typu varchar. Postup vyplní seznam souborů z umístění uvedeného v parametru a vloží všechny soubory do Document_Content tabulka.

Krok 1:Změňte konfigurační parametr.

Chcete-li spustit příkaz PowerShell pomocí T-SQL, povolte xp_cmdshell možnost konfigurace. Je to pokročilá možnost konfigurace; tedy před povolením xp_cmdshell , povolte možnostZobrazit pokročilé možnost konfigurace. Za tímto účelem spusťte postupně následující příkazy T-SQL.

použijte mastergoexec sp_configure 'show advanced options',1reconfigure with overrideExec sp_configure 'xp_cmdshell',1Reconfigure with override

Krok 2:Použijte skript PowerShell k naplnění seznamu souborů v kódu T-SQL

Chcete-li spustit skript PowerShell pomocí T-SQL, použijte xp_cmdshell postup. Spustí příkaz PowerShell, který vyplní seznam souborů a jeho podrobnosti v Seznam_dokumentů table.
Kód je následující:

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

Krok 3:Vytvořte dynamický dotaz SQL pro zjištění umístění souboru

Vytvořte dynamický SQL dotaz, který bude iterován přes Document_List tabulka, načte obsah souboru, který se nachází na cestě uvedené v Celé jméno sloupec, převede jej na sloupec VARBINAR(MAX) a vloží jej do Document_Content stůl. Spolu se souborem skript vloží název souboru, atribut souboru, velikost souboru a typ souboru do Document_Content stůl. Skript používá případ výraz pro určení typu souboru.

Kód je následující:

SET @FileCount =(SELECT Count(*) FROM Document_List) WHILE ( @i <@FileCount ) ZAČNĚTE SET @FileName =(VYBERTE TOP 1 název ZE Document_List) /* Spojte sloupec DirectoryLocation a FileName pro vygenerování FQDN. */ SET @FileName =(VYBERTE NEJLEPŠÍ 1 název ZE seznamu_dokumentů) SET @Umístění souboru =(VYBERTE NEJLEPŠÍ 1 celé jméno ZE seznamu_dokumentů kde jméno=@Název_souboru) SET @FileAttribute =(VYBERTE NEJLEPŠÍ 1 atributy ZE seznamu_dokumentů kde jméno=@Název_souboru) SET @ FileCreateDate =(VYBERTE NEJLEPŠÍCH 1 Čas vytvoření Z Document_List kde jméno=@FileName) SET @FileSize =(VYBERTE NEJLEPŠÍ 1 délku Z Document_List kde název=@FileName) SET @FileType =(VYBERTE 1 NEJLEPŠÍ PŘÍPAD, KDYŽ ( název LIKE '%jpg%' ) OR ( name LIKE '%png%' ) OR ( name LIKE '%jpg%' ) OR ( name LIKE '%bmp%' ) THEN 'Images' WHEN ( name LIKE '%txt%' )THEN 'Text Files' When ( název LIKE '%xls%' )THEN 'Textové soubory' When ( název LIKE '%doc%' ) THEN 'Textové soubory' ELSE 'Ostatní soubory' KONEC JAKO 'Typ souboru' FROM Document_List where name=@FileName) SET @SQLText ='Vložit do Document_Content (ID, RootDirectory, FileName, FileAttribute,FileCreateDate,FileSize,FileType,FileStreamCol) Vyberte NEWID(), 'leLo'' + ''', ''' + @FileName + ''', ''' + @FileAttribute + ''', ''' + @FileCreateDate + ''', ''' + @FileSize + ''', ' '' + @FileType + ''', bulkColumn z Openrowset (Hromadné '''+ @FileLocation + ''', Single_Blob) jako tb' EXEC Sp_executesql @SQLText DELETE FROM Document_List WHERE name =@FileName SET @I =@I + 1END

Krok 4:Zabalte celý kód SQL do uložené procedury

Vytvořte parametrizovanou uloženou proceduru s názvem sp_Insert_Files a zabalte do něj kód.

Kód uložené procedury je následující:

použijte proceduru FileStream_DemogoCreate sp_Insert_Files@FileLoc varchar(max)as begin DECLARE @FileCount INTDECLARE @I INT =0DECLARE @FileName NVARCHAR(max)DECLARE @SQLText NVARCHAR(max)declare @PSScript varchar(2500CH) )declare @FileAttribute varchar(50)declare @FileCreateDate varchar(50)declare @FileSize varchar(10)declare @FileType varchar(20)set @PSScript='powershell.exe getFileList ''' + @FileLoc +'''' ex xp_cmdshell @PSScriptSET @FileCount =(SELECT Count(*) FROM Document_List) WHILE ( @i <@FileCount ) BEGIN /* Získání názvu souboru z tabulky Document_Name */ SET @FileName =(SELECT TOP 1 název FROM Document_List) /* Naplnění Podrobnosti o souboru z tabulky Document_List*/ SET @FileName =(VYBRAT NEJLEPŠÍ 1 název ZE seznamu_dokumentů) SET @FileLocation =(VYBRAT NEJLEPŠÍ 1 celé jméno Z Document_List kde jméno=@FileName) SET @FileAt hold =(VYBERTE NEJLEPŠÍCH 1 atributů FROM Document_List kde název=@FileName) SET @FileCreateDate =(SELECT TOP 1 CreationTime FROM Document_List where name=@FileName) SET @FileSize =(SELECT TOP 1 Length FROM Document_List where name=@FileName) / *Určete typ souboru*/ SET @FileType =(VYBERTE 1 NEJLEPŠÍ PŘÍPAD, KDYŽ ( název LIKE '%jpg%' ) OR ( název LIKE '%png%' ) OR ( název LIKE '%jpg%' ) OR ( název LIKE '%bmp%' ) THEN 'Images' WHEN ( název LIKE '%txt%' )THEN 'Text Files' When ( name LIKE '%xls%' )THEN 'Text Files' When ( name LIKE '%doc%' ) POTOM 'Textové soubory' ELSE 'Ostatní soubory' KONČÍ JAKO 'Typ souboru' Z Document_List kde name=@FileName) SET @SQLText ='Vložit do Document_Content (ID, RootDirectory, FileName, FileAtt ribute,FileCreateDate,FileSize,FileType,FileStreamCol) Vyberte 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

Vložit soubory pomocí uložené procedury

Nyní otestujte uloženou proceduru. Přidal jsem několik souborů do E:\Files adresář. Vložte soubory do tabulky SQL provedením uložené procedury. Kód je následující:

použijte FileStream_Demogoexec sp_Insert_Files 'E:\Files'

Ověřte, že soubory byly zkopírovány do tabulky. Za tímto účelem spusťte následující kód:

vyberte RootDirectory jako 'Umístění souboru', FileName jako 'Název souboru', FileAttribute jako 'Atribut', FileCreateDate jako 'Atribut', FileSize jako 'Velikost souboru', FileType jako 'Typ souboru', FileStreamCol jako 'Obsah souboru' z Document_Content, kde FileType='Images'

Výstup dotazu je následující:

Chcete-li získat přístup k souboru v úložišti dat FILESTREAM pomocí rozhraní Win32 API, použijte Cesta () metoda FILESTREAM. SNázev cesty () můžeme jednoznačně identifikovat logickou cestu k detekci souboru v datovém úložišti FILESTREAM.

Kód je následující:

vyberte RootDirectory jako 'Umístění souboru', FileName jako 'Název souboru', FileAttribute jako 'Atribut', FileCreateDate jako 'Atribut', FileSize jako 'Velikost souboru', FileType jako 'Typ souboru', FileStreamCol.PathName() AS FilePathfrom Document_Content kde FileName='RowDesign.png'

Výstup dotazu je následující:

Přejdeme do datového kontejneru FILESTREAM (E:\Dummy-Documents) a ověříme, zda byly soubory vloženy. Viz následující snímek obrazovky:

Jak můžete vidět, všechny soubory byly vloženy do tabulek SQL a kontejneru FileStream.

Shrnutí

V tomto článku jsem se zabýval:

  1. Užitečný dotaz k ověření předpokladů funkce FILESTREAM.
  2. Jak zaregistrovat funkci PowerShell jako modul.
  3. Vysvětlete kód PowerShellu pro vložení seznamu souborů do tabulky SQL pomocí skriptu PowerShell.
  4. Vysvětlil kód uložené procedury pro vložení více souborů do tabulky SQL.
  5. Užitečné dotazy pro získání seznamu dokumentů uložených v kontejneru FILESTREAM.

V budoucích článcích vysvětlím, jak zálohovat a obnovit databázi s povoleným FILESTREAM.

Zůstaňte naladěni!


  1. zvýšit číslo řádku, když se změní hodnota pole v Oracle

  2. Jak počítat slova v MySQL / náhradě regulárních výrazů?

  3. SQL Server ROWCOUNT_BIG()

  4. Jak změnit hodnotu automatického přírůstku databáze MySQL / MariaDB