FILESTREAM - SQLClub
На http://sqlclub. ru/forum/ у мене свого часу була аналогічна тема. Однак sqlclub.ru в даний час недоступний через непорядність людини на ім'я Сергій Заворуєв, який, мабуть, вирішив тишком-нишком присвоїти контент. Доведеться повторити цю тему тут, бо незабаром вона нам знадобиться.
Для підтримки типу FileStream потрібно на рівні бази завести відповідну файл-групу. Як flename для цієї групи виступає локальна папка у файловій системі. Ми не можемо взяти файл по довільному шляху, підсунути його SQL Server і сказати: дивися, це буде твоїм полем файл стрім в такому записі. Як ми побачимо далі, ми можемо лише скопіювати вміст цього файлу в полі, а зберігатиметься він у тому файлі, який відведе йому SQL Server і назве відповідно до своїх правил.
if exists( select 1 from sys . databases where name = 'TestFS' ) begin
alter database TestFS set single_user with rollback immediate
drop database TestFS
create database TestFS on
primary ( name = TestFS_data , filename = 'c:\Temp\TestFS_data.mdf' ),
filegroup FG1 contains filestream
( name = TestFS_media , filename = 'c:\Temp\TestFS_media' )
log on (name = TestFS_log, filename = 'c:\Temp\TestFS_log.ldf')
Ось що з'явилося після створення бази в директорії c:\Temp:

Прописаний у filestreamівській групі filename являє собою фолдер на локальному диску. Якщо запропонувати файлову кулю, обматерить:
create database TestFS1 on
primary (name = TestFS_data, filename = 'c:\Temp\TestFS_data.mdf'),
filegroup FG1 contains filestream
(name = TestFS_media, filename = '\192.168.0.1\c$\Temp\TestFS_media')
logon (name = TestFS_log, filename = 'c:\Temp\TestFS_log.ldf')
Msg 5135, Level 16, State 2, Line 1
The path '\192.168.0.1\c$\Temp\TestFS_media' може бути використаний для FILESTREAM files. Для отримання інформації про supported paths, pozri SQL Server Books Online.
Msg 1802, Level 16, State 2, Line 1
CREATE DATABASE failed. Кілька файлів наклейок не можна створювати. Check related errors.
Зазначений шлях має існувати аж до n -1-го рівня, у разі - c:\Temp. Фолдер TestFS_media існувати не повинен.
Можна створювати кілька файл-груп типу файл стрім:
create database TestFS1 on
primary ( name = TestFS_data , filename = 'c:\Temp\TestFS_data1.mdf' ),
filegroup FG1 contains filestream
( name = TestFS_media1 , filename = 'c:\Temp\TestFS_media1' ),
filegroup FG2 contains filestream
( name = TestFS_media2 , filename = 'c:\Temp\TestFS_media2' )
log on (name = TestFS_log, filename = 'c:\Temp\TestFS_log1.ldf')
однак у файл стримівській файл групі може бути прописаний лише один фолдер. Так робити не можна:
filegroup FG 1 contains filestream
(name = TestFS_media, filename = 'c:\Temp\TestFS_media'),
(name = aaa, filename = 'c:\aaa')
Тобто. автоматично розганяти файл стримівські файли по різних папках не вийде.
Після створення бази з файл стримівської файл-групою можна створювати таблиці з файл стримівськими полями. В операторі CREATE TABLE поле типу filestream – це звичайний блоб (varbinary (max)) з атрибутом filestream.
create table Media (
>int identity primary key ,
[gu >uniqueidentifier default newid() unique rowguidcol not null,
[fileName] nvarchar ( 256 ),
contentTypenvarchar ( 256 ),
blob nvarchar (max),
stream varbinary ( max ) filestream
За наявності у таблиці поля filestream обов'язковим також є наявність поля unique lang=RU> Хоча unique > на те й unique lang=RU>, щоб бути unique , ця умова потрібна, щоб, наприклад, новий запис не потрапило значення з попередньої. Крім того, оптимізатор набагато радісніше почувається, коли бачить явний unique. Атрибут rowguidcol дозволяє звертатися до поля не на ім'я, а як $ rowgu lang=RU>: напр., select $rowguid from Media. Зрозуміло, що таке поле має бути одне на таблицю. Яку важливість привносить цей атрибут, я, чесно кажучи, сказати не беруся. Просто бувають ситуації, які його вимагають, і тому. Раніше до них належала merge-реплікація, зараз ось додався файл стрім.
Наявність primary key є обов'язковим. В даному випадку ми могли б обійтись без поля > простіше, ніж запам'ятовувати гуїд.
Апостеріори дізнатися, чи має поле атрибут filestream, можна так:
select * from sys. columns where object_id = object_id ( 'Media' , 'table' ) and system_type_ >= type_id ( 'varbinary' ) and max_length = - 1 and is_filestream = 1
Після створення таблиці в C:\Temp\TestFS_media (параметр filename групи filestream при створенні бази) з'явилася директорія на ім'я деякого гуїда, що відповідає таблиці, в ній - ще одна теж з ім'ям якогось гуїда, що відповідає полю filestream у цій таблиці (їх може бути кілька за кількістю таких полів).



Давайте тепер додавати до неї записи:
insert Media ( stream ) values ( cast ( N'aaa' asvarbinary (max)))
insert Media ( stream ) values ( cast ( N'bbb' as varbinary ( max )))
insert Media ( stream ) values ( cast ( N'ccc' as varbinary ( max )))
Після вставки в листовій директорії з'явилося три файли з іменами гуїдів, що відповідають трьом вставленим записам. Під NULLове значення файл не заводиться, у блобі має бути щось непусте. Порожній рядок – це вже не порожнеча.

Ось ми його підредагували:
зберегли та подивилися, що вийшло:
select *, cast (stream as nvarchar (max)) from Media

Як приклад того, як це все перебуває під контролем SQL Server, подивимося, як файл стрим бекапаться разом з базою. Робимо
backup database TestFS на диск = 'c:\Temp\Test_FS.bak' with init
Потім драпаємо базу, при цьому фолдер TestFS_media зникає з c: \ Temp разом з усіма своїми файлами, в яких зберігалося вміст поле файл стрім від різних записів таблиці Media. Ресторим базу:
restore database TestFS від диску = 'c:\Temp\Test_FS.bak' with move 'TestFS_media' до 'c:\aaa'

Тут W I TH MOVE – стандартна опція, в якій при відновленні вказується, що логічні імена файлів тепер відповідатимуть іншим фізичним шляхам. Ми говоримо, що c:\Temp\TestFS_media переїжджає у з:\aaa. При цьому на диску з автоматично створюється фолдер aaa, куди розгорнулася файл стримівська файл група. Так само, як і під час створення бази, весь зазначений шлях має існувати від кореня диска рівня n-1, тобто. якби ми сказали with move 'TestFS_media' to 'c:\aaa\bbb', не прокотило б.
Як і HierarchyID, про який я неабияк розмовляв у попередніх постах, і геопросторові типи, розмови на тему яких щепопереду, тип filestream підтримується в безкоштовному SQL Server, який SQL Express. Більш того, обмеження на розмір бази для SQL Express не поширюються на дані, що лежать у файл стримівських блобах.