Wczytywanie plików do FILESTREAM odbywa się przez API systemu plików lub standardowe operacje na kolumnie binarnej.
Wczytywanie plików do kolumny FILESTREAM w SQL Server
FILESTREAM to mechanizm programu Microsoft SQL Server przeznaczony do przechowywania dużych danych binarnych, takich jak dokumenty, obrazy, nagrania lub archiwa, przy jednoczesnym zachowaniu ich powiązania z rekordami tabeli. Kolumna przeznaczona do takiego przechowywania musi mieć typ varbinary(max) oraz atrybut FILESTREAM. Dane są wtedy zarządzane przez SQL Server, ale ich zawartość jest przechowywana w specjalnym obszarze systemu plików określanym jako kontener FILESTREAM. Nie należy modyfikować plików w tym kontenerze bezpośrednio za pomocą Eksploratora Windows ani zwykłych funkcji kopiowania, ponieważ SQL Server kontroluje ich nazwy, powiązania i spójność transakcyjną.
Wczytanie pliku może zostać wykonane na dwa podstawowe sposoby. Pierwszy wykorzystuje standardowe operacje na kolumnie binarnej, czyli instrukcje Transact-SQL INSERT albo UPDATE. Drugi korzysta ze strumieniowego interfejsu systemu plików udostępnianego przez SQL Server. Wybór metody zależy przede wszystkim od rozmiaru pliku, używanego sterownika, aplikacji oraz wymagań dotyczących wydajności. Zwykła operacja T-SQL jest prostsza, natomiast interfejs strumieniowy ogranicza konieczność przesyłania całej zawartości przez warstwę relacyjną.
Operacje T-SQL przy zapisie danych binarnych
Najprostszy zapis polega na przekazaniu zawartości pliku jako wartości binarnej do instrukcji INSERT. Aplikacja odczytuje plik, a następnie przekazuje bajty do parametru typu varbinary(max). W przypadku istniejącego rekordu używa się instrukcji UPDATE. Parametryzowanie zapytania jest istotne, ponieważ pozwala uniknąć ręcznego składania literałów binarnych i ogranicza ryzyko błędów związanych z kodowaniem, długością danych lub nieprawidłowym cytowaniem wartości.
Przykładowy schemat tabeli może zawierać klucz główny, nazwę pliku oraz kolumnę binarną:
CREATE TABLE Dokumenty (DokumentId uniqueidentifier ROWGUIDCOL NOT NULL UNIQUE, Nazwa nvarchar(260) NOT NULL, Tresc varbinary(max) FILESTREAM NULL);
W praktycznej definicji kolumny FILESTREAM wymagane jest także utworzenie tabeli z odpowiednim obszarem FILESTREAM, a kolumna identyfikatora wiersza musi mieć właściwość ROWGUIDCOL i ograniczenie unikalności. Po utworzeniu rekordu aplikacja może wykonać parametrów zapisu, na przykład przekazując bajty do kolumny Tresc. Jeżeli kolumna dopuszcza wartość NULL, można najpierw utworzyć rekord z pustą zawartością, a następnie uzupełnić go w ramach osobnej operacji. Dla większych plików należy kontrolować rozmiar parametrów, czas trwania transakcji i obsługę błędów połączenia.
Strumieniowy interfejs OpenSqlFilestream
SQL Server udostępnia funkcję OpenSqlFilestream, która pozwala aplikacji otworzyć uchwyt do danych FILESTREAM i przesyłać je za pomocą interfejsu systemu plików Windows. Przed wywołaniem tej funkcji aplikacja musi uzyskać ścieżkę logiczną do danych, zwykle przez odczytanie wartości PathName() dla konkretnego wiersza. Musi także pobrać kontekst transakcji FILESTREAM przez funkcję GET_FILESTREAM_TRANSACTION_CONTEXT(). Kontekst ten jest powiązany z aktywną transakcją SQL Server i służy do autoryzacji operacji na strumieniu.
Typowy przepływ zapisu obejmuje rozpoczęcie transakcji, przygotowanie lub odszukanie rekordu, pobranie ścieżki logicznej i kontekstu transakcji, a następnie otwarcie strumienia z odpowiednimi prawami dostępu. Aplikacja zapisuje dane porcjami, zamyka uchwyt i zatwierdza transakcję. Jeżeli wystąpi błąd, transakcję należy wycofać, a uchwyt zamknąć zgodnie z zasadami używanego języka programowania. Pominięcie zatwierdzenia albo wycofania może powodować blokady i pozostawienie operacji w stanie nieukończonym. Przy zapisie przez API należy również zachować kolejność operacji, ponieważ ścieżka FILESTREAM i kontekst transakcji nie są niezależnymi, trwałymi uprawnieniami do katalogu systemu plików.
Spójność transakcji, konfiguracja i diagnostyka zapisu
FILESTREAM musi być włączony zarówno na poziomie instancji SQL Server, jak i odpowiednio skonfigurowany dla bazy danych oraz tabeli. Sama kolumna varbinary(max) FILESTREAM nie wystarczy, jeżeli instancja nie ma aktywnej obsługi FILESTREAM. Znaczenie ma także dostęp do strumieniowego interfejsu Win32 oraz konfiguracja udziału FILESTREAM, ponieważ operacje wykonywane przez OpenSqlFilestream korzystają z mechanizmu systemu plików kontrolowanego przez SQL Server. W środowisku lokalnym i sieciowym należy sprawdzić, czy aplikacja łączy się z właściwą instancją oraz czy używa odpowiedniego protokołu dostępu.
Problemy z wczytywaniem mogą wynikać z braku aktywnego kontekstu transakcji, użycia nieaktualnej wartości ścieżki, zamknięcia transakcji przed zakończeniem zapisu, braku uprawnień albo niezgodności sposobu połączenia z wymaganiami FILESTREAM. Diagnostyka powinna obejmować sprawdzenie definicji tabeli, wartości zwracanej przez PathName(), wyniku GET_FILESTREAM_TRANSACTION_CONTEXT(), statusu transakcji oraz rozmiaru zapisywanego pliku. Należy także rozróżnić błąd aplikacji od błędu SQL Server: nieudane odczytanie pliku lokalnego następuje przed wysłaniem danych do bazy, natomiast błąd kontekstu lub uchwytu wskazuje zwykle na niewłaściwą sekwencję operacji FILESTREAM.