Transact-SQL を使用して FILESTREAM データにアクセスする

適用対象:SQL Server

この記事では、Transact-SQL INSERT、UPDATE、DELETE ステートメントを使用して FILESTREAM データを管理する方法について説明します。

注意

この記事の例では、「FILESTREAM-Enabled データベースの作成」および「FILESTREAM データを格納するためのテーブルの作成」で作成した FILESTREAM 対応データベースとテーブルが必要です。

FILESTREAM データを含む行を挿入する

FILESTREAM データをサポートするテーブルに行を追加するには、Transact-SQL INSERT ステートメントを使用します。 データを FILESTREAM 列に挿入するときは、NULL または varbinary(max) 値を挿入できます。

NULL を挿入する

NULLを挿入する方法を次の例に示します。 FILESTREAM 値が の NULL場合、データベース エンジンはファイル システムにファイルを作成しません。

INSERT INTO Archive.dbo.Records
    VALUES (NEWID(), 1, NULL);
GO

長さ 0 のレコードを挿入する

INSERT を使用して長さ 0 のレコードを作成する方法を次の例に示します。 これは、ファイル ハンドルを取得する必要がある場合に役立ちますが、Win32 API を使用してファイルを操作します。

INSERT INTO Archive.dbo.Records
    VALUES (NEWID(), 2, 
      CAST ('' AS VARBINARY(MAX)));
GO

データ ファイルを作成する

INSERT を使用して、データを含むファイルを作成する方法を次の例に示します。 データベース エンジン によって、文字列 Seismic Datavarbinary(max) 値に変換されます。 FILESTREAM は、Windows ファイルがまだ存在しない場合に作成します。 その後、データがデータ ファイルに追加されます。

INSERT INTO Archive.dbo.Records
    VALUES (NEWID(), 3, 
      CAST ('Seismic Data' AS VARBINARY(MAX)));
GO

すべてのデータを Archive.dbo.Records テーブルから選ぶと、次の表に示すような結果になります。 ただし、 Id 列に格納される GUID は異なります。

id SerialNumber グラフ
C871B90F-D25E-47B3-A560-7CC0CA405DAC 1 NULL
F8F5C314-0559-4927-8FA9-1535EE0BDF50 2 0x
7F680840-B7A4-45D4-8CD5-527C44D35B3F 3 0x536569736D69632044617461

FILESTREAM データを更新する

Transact-SQL を使用してファイル システム ファイル内のデータを更新できますが、大量のデータをファイルにストリーミングする場合は、これを行わない場合があります。

ファイル レコード内の任意のテキストを、 Xray 1というテキストに置換する例を次に示します。

UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' AS VARBINARY(MAX))
WHERE [SerialNumber] = 2;

FILESTREAM データを削除する

FILESTREAM フィールドを含む行を削除すると、その基となるファイル システム ファイルも削除されます。 行を削除する唯一の方法(したがってファイル)は、Transact-SQL DELETE ステートメントを使用することです。

行およびそれに関連付けられているファイル システム ファイルを削除する方法を次の例に示します。

DELETE Archive.dbo.Records
WHERE SerialNumber = 1;
GO

テーブルからすべてのデータを Archive.dbo.Records 選択すると、行が削除され、関連付けられているファイルを使用できなくなります。

注意

基になるファイルは、FILESTREAM ガベージ コレクターによって削除されます。

テーブルまたはデータベースに FILESTREAM データが含まれているかどうかを確認する

データベースまたはテーブルに FILESTREAM データが含まれているかどうかを調べるには、システム ビューに対してクエリを実行する必要があります。

次の拡張例は、新しいデータベースを作成し、FILESTREAM データを持つテーブルを作成し、システム ビューにクエリを実行して、テーブルとデータベース自体に FILESTREAM データが含まれているかどうかを確認する手順を示しています。

USE [master];
GO

-- Create database with FILESTREAM
CREATE DATABASE [FileStreamTest] CONTAINMENT = NONE ON PRIMARY (
    NAME = N'FileStreamTest'
    , FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\FileStreamTest.mdf'
    , SIZE = 204800 KB
    , MAXSIZE = UNLIMITED
    , FILEGROWTH = 65536 KB
    )
    , FILEGROUP [FileStreamFG] CONTAINS FILESTREAM DEFAULT(NAME = N'FileStreamTestFStream', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\FileStreamTestFStream', MAXSIZE = UNLIMITED) LOG ON (
    NAME = N'FileStreamTest_log'
    , FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\FileStreamTest_log.ldf'
    , SIZE = 270336 KB
    , MAXSIZE = 2048 GB
    , FILEGROWTH = 65536 KB
    )
    WITH CATALOG_COLLATION = DATABASE_DEFAULT;
GO

USE [FileStreamTest];
GO

CREATE TABLE FSTiffs (
    Guid UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWSEQUENTIALID()
    , DocumentID INT NOT NULL
    , DocumentType VARCHAR(10) NOT NULL
    , FileContent VARBINARY(MAX) FILESTREAM NOT NULL
    , DateInserted DATETIME
);

-- Which database and files use FILESTREAM 
SELECT db_name(database_id) dbname
    , name AS file_name
    , physical_name
    , type_desc
    , *
FROM sys.master_files
WHERE type_desc = 'FILESTREAM';

-- Which tables in the database have FILESTREAM enabled
USE [FileStreamTest]
GO

SELECT *
FROM sys.tables
WHERE filestream_data_space_id IS NOT NULL;

--insert a TIFF file
INSERT INTO FSTiffs (
    DocumentID
    , DocumentType
    , FileContent
    , DateInserted
    )
SELECT 101
    , '.tiff'
    , *
    , GETDATE()
FROM OPENROWSET(BULK N'C:\Temp\Sample1.tiff', SINGLE_BLOB) rs;

-- Select data from FILESTREAM table
SELECT *
FROM FSTiffs;

-- Update a document
UPDATE FSTiffs
SET FileContent = (
        SELECT *
        FROM OPENROWSET(BULK N'C:\Temp\Sample2.tiff', SINGLE_BLOB) AS rs
        )
WHERE DocumentID = 101;

-- Delete a document
DELETE FSTiffs
WHERE DocumentID = 101;

--clean up any delete files
EXEC sp_filestream_force_garbage_collection @dbname = N'FileStreamTest'
    , @filename = N'FileStreamTestFStream';

こちらもご覧ください