Мы продолжаем публикацию блогов по FILESTREAM.
В этом блоге мы рассмотрим методы доступа к данным FILESTREAM. Возможно в данной статье для вас не будет ничего нового, но мы решили опубликовать его, чтобы наш разговор о FILESTREAM был логично завершен.
Для доступа к FILESTREAM есть две возможности:
Здесь все достаточно понятно и прозрачно. Для доступа используются стандартные DML-операторы, SELECT, INSERT, DELETE, UPDATE.
Особенностью операции UPDATE является то, что она не поддерживает частичное обновление файла и как результат выполняется как операция DELETE/INSERT.
Ниже приведены примеры выполнения таких операторов.
INSERT INTO dbo.FS_Records (Document)
VALUES (CAST(‘Yes, it””s work fine’ as varbinary(max)));
GO
SELECT *, cast (fsr.Document as char(100) ) as [Document text]
FROM dbo.FS_Records fsr;
GO
UPDATE FS_Records
SET Document = CAST(‘It is updated column’ as varbinary(max))
WHERE DocId = 2;
GO
Единственно необычной вещью здесь является функция PathName(). В общем-то, для работы через Transact-SQL она не нужна, но через нее можно получить путь к файлу, который потом может быт передан в метод Win API для доступа к файлу лежащему на файловой системе.
Как было показано в предыдущих статьях эта функция не возвращает реального пути, но она дает точку перенаправления через драйвер RsFx0300xx к SQL Server-у.
Далее приводится пример доступа к FILESTREAM-файлам через Win API.
Пример написан на языке C# и имеет комментарии для каждой строки.
using System.IO;
using System;
using System.Data.SqlClient;
using System.Data.SqlTypes;
namespace FILESTREAM
{
class Program
{
static void Main(string[] args)
{
string DocId = args[0]; //Параметр передаваемый из командной строки.
SqlConnection sqlConnection = new SqlConnection(“Integrated Security=true;server=localhost\\SQL2014”); //Устанавливаем соединение к серверу
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
try
{
sqlConnection.Open();
// Первое, что необходимо сделать, это получить путь к файлу SQL FILESTREAM BLOBа, через который приложение будет получать доступ к данным хранящимся в
этом SQL FILESTREAM BLOB.
// Для получения пути к файлу используется функция PathName().
sqlCommand.CommandText = “SELECT Document.PathName() FROM FileStreamTest.dbo.FS_Records where DocId =” + DocId; //DocId – это аргумент, переданный из командной строки.
String filePath = null;
Object pathObj = sqlCommand.ExecuteScalar();
// Путь будет представлять строку типа
// “\\\\ALEXAK-WS1\\SQL2014_FileStream\\v02-A60EC2F8-2B24-11DF-9CC3-AF2E56D89593\\FileStreamTest\\dbo\\FS_Records\\Document\\1895BA5E-F64E-45C5-9E22-65D225A69BD9\\VolumeHint-HarddiskVolume6”
// С помощью даной строки будет осуществлено перенаправление запроса через общий ресурс \\ALEXAK-WS1\SQL2014_FileStream на реальный файл, как это описано в наших предыдущих блогах.
if(pathObj==null)
{
throw new System.Exception(“There is no such Documents”);
}
if (DBNull.Value != pathObj)
{
filePath = (string)pathObj;
}
else
{
throw new System.Exception(“Document.PathName() failed to read the path name for the Document column.”);
}
// Далее необходимо получить контекст транзакции.
// Все FILESTREAM BLOB операции ДОЛЖНЫ происходят внутри транзакций для того, чтобы избежать конфликтов с другими транзакциями,
// например c транзакциями MARS, происходящими внутри специфических batch scoped транзакций.
SqlTransaction fsTran = sqlConnection.BeginTransaction(“FileStreamTran”);
sqlCommand.Transaction = fsTran;
//Получаем контекст транзакции
sqlCommand.CommandText =“SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()”;
Object 3 авг. 2017 г.