Serwisanci dostępni teraz · czynne całą dobę, także w weekendy i świętaWarszawa i okolice · dojazd bezpłatny
Darmowa diagnoza laptopa
Darmowa diagnoza laptopa
Dojazd do klienta bezpłatnie
Dojazd do klienta bezpłatnie
Laptopy zastępcze bezpłatnie
Laptopy zastępcze bezpłatnie
Odbiór i zwrot sprzętu bezpłatnie
Odbiór i zwrot sprzętu bezpłatnie

Zapis danych FILESTREAM

Termin Definicja
Zapis danych FILESTREAM

Zapis danych FILESTREAM odbywa się przez API systemu plików lub standardowe operacje na kolumnie binarnej.

Jak SQL Server zapisuje dane FILESTREAM

FILESTREAM to funkcja Microsoft SQL Server przeznaczona do przechowywania dużych wartości binarnych typu varbinary(max) w systemie plików NTFS, przy zachowaniu transakcyjnej kontroli po stronie bazy danych. Tabela korzystająca z FILESTREAM musi mieć kolumnę typu varbinary(max) FILESTREAM oraz kolumnę ROWGUIDCOL typu uniqueidentifier z ograniczeniem UNIQUE. Kolumna oznaczona atrybutem FILESTREAM nie jest zwykłym polem wskazującym dowolny katalog. SQL Server sam zarządza właściwym kontenerem danych i wiąże zapis pliku z konkretnym wierszem tabeli.

Dane można zapisywać za pomocą standardowych instrukcji Transact-SQL, takich jak INSERT i UPDATE. W takim przypadku aplikacja przekazuje wartość binarną do kolumny, a silnik SQL Server zapisuje ją w ramach transakcji. Dla większych obiektów dostępna jest również metoda oparta na strumieniowaniu przez interfejs systemu plików Windows. Nie polega ona na ręcznym kopiowaniu plików do katalogu FILESTREAM, lecz na użyciu uchwytu zwróconego przez SQL Server i obsłudze zapisu zgodnie z regułami transakcji bazy.

Kolumna FILESTREAM, filegroup i kontener danych

Przed zapisem trzeba utworzyć bazę danych z filegroup oznaczonym jako FILESTREAM, a następnie wskazać kontener FILESTREAM w definicji bazy. Przykładowa konfiguracja może zawierać filegroup z opcją CONTAINS FILESTREAM oraz ścieżkę kontenera podaną w klauzuli FILESTREAM. Lokalizacja kontenera jest zarządzana przez SQL Server i nie powinna być modyfikowana bezpośrednio przez użytkownika ani aplikację. Pliki widoczne w tym obszarze mają wewnętrzne nazwy oraz strukturę techniczną, dlatego operacje systemowe wykonywane poza SQL Server mogą doprowadzić do niespójności danych.

Przykładowa tabela przechowująca dokumenty może mieć kolumny DocumentId uniqueidentifier ROWGUIDCOL NOT NULL UNIQUE, FileName nvarchar(255) oraz Content varbinary(max) FILESTREAM NULL. Podczas zapisu wiersza aplikacja musi dostarczyć identyfikator GUID spełniający wymagania kolumny ROWGUIDCOL. Sam atrybut FILESTREAM nie zmienia typu logicznego danych: z perspektywy zapytań SQL zawartość nadal jest wartością varbinary(max), natomiast sposób fizycznego przechowywania i dostęp strumieniowy są obsługiwane przez SQL Server.

Zapis strumieniowy przez API systemu plików Windows

Przy zapisie dużego obiektu aplikacja może najpierw utworzyć lub zaktualizować wiersz w Transact-SQL, a następnie pobrać ścieżkę logiczną za pomocą funkcji PathName(). Ta ścieżka jest używana razem z funkcją OpenSqlFilestream(), która zwraca uchwyt pozwalający czytać albo zapisywać zawartość przez system plików. Operacja wymaga aktywnej transakcji SQL Server oraz wartości kontekstu transakcji pobranej funkcją GET_FILESTREAM_TRANSACTION_CONTEXT(). Bez tego kontekstu SQL Server nie może powiązać operacji plikowej z właściwą transakcją.

Typowy przebieg zapisu obejmuje rozpoczęcie transakcji, przygotowanie wiersza z kolumną FILESTREAM, pobranie ścieżki i kontekstu transakcji, otwarcie uchwytu w trybie zapisu, przekazanie danych blokami przez operacje wejścia-wyjścia oraz zatwierdzenie transakcji po poprawnym zakończeniu zapisu. Jeżeli transakcja zostanie wycofana albo uchwyt nie zostanie prawidłowo zamknięty, zapis nie powinien być traktowany jako ukończony. Aplikacja musi także obsłużyć błędy częściowego zapisu, przerwanie połączenia oraz sytuację, w której transakcja wygasa przed zakończeniem przesyłania danych.

Strumieniowanie FILESTREAM nie jest tym samym co otwarcie pliku z przypadkowej ścieżki systemowej. SQL Server kontroluje dostęp na podstawie wpisu w tabeli, kontekstu transakcji i uprawnień. Funkcja OpenSqlFilestream() jest przeznaczona do dostępu do danych FILESTREAM z poziomu aplikacji Windows i wymaga poprawnie skonfigurowanej funkcji FILESTREAM oraz odpowiednich uprawnień do bazy i obiektu. W praktyce wybór między Transact-SQL a dostępem strumieniowym zależy od rozmiaru danych, używanego sterownika i sposobu działania aplikacji.

Kontrola poprawności zapisu i objawy problemów

Po zapisie warto sprawdzić, czy transakcja została zatwierdzona, czy wiersz zawiera oczekiwany identyfikator oraz czy długość danych zwracana przez zapytanie odpowiada przekazanemu obiektowi. Do kontroli można wykorzystać między innymi funkcję DATALENGTH() dla kolumny FILESTREAM. Należy rozróżnić wartość NULL, pustą wartość binarną oraz zapis przerwany przed zatwierdzeniem. Błąd w logice aplikacji może polegać na zapisaniu metadanych pliku bez treści, zatwierdzeniu wiersza przed zakończeniem transferu albo rozpoczęciu operacji strumieniowej bez aktywnego kontekstu transakcji.

Diagnostyka obejmuje sprawdzenie definicji tabeli, obecności wymaganej kolumny ROWGUIDCOL, konfiguracji filegroup FILESTREAM, ustawień instancji SQL Server oraz uprawnień konta wykonującego operację. Nie wolno naprawiać problemu przez ręczne usuwanie, przenoszenie lub zmienianie plików w kontenerze FILESTREAM. Jeżeli dane binarne są uszkodzone albo zapis kończy się błędem, należy zachować informacje o numerze błędu SQL Server, przebiegu transakcji, rozmiarze przesyłanego obiektu i użytej metodzie dostępu, a następnie zweryfikować spójność na poziomie bazy oraz aplikacji.

FILESTREAM łączy więc dwa sposoby pracy: logiczny zapis kolumny binarnej przez SQL Server i kontrolowany dostęp strumieniowy przez API Windows. W obu przypadkach źródłem prawdy pozostaje tabela oraz transakcja SQL Server, a nie katalog widoczny na dysku. Prawidłowa implementacja nie kopiuje plików bezpośrednio do kontenera, tylko korzysta z mechanizmów udostępnionych przez konkretną instancję SQL Server.

+48 22 100 48 29Zadzwoń teraz · serwisant w 1 godzinę