【问题标题】:Accessing Sql FILESTREAM from within a CLR stored procedure从 CLR 存储过程中访问 Sql FILESTREAM
【发布时间】:2009-09-01 11:11:49
【问题描述】:

我正在尝试从 CLR 存储过程访问 Sql 文件流。我已经建立了一个非常简单的数据库,其中包含一个包含文件流列的单个表。我可以使用一个简单的控制台应用程序成功地从文件流中读取。这是失败的proc的一些示例代码:

[SqlProcedure]
public static void GetDataFromFileStream(string path, out int data)
{
    using (var connection = new SqlConnection("context connection=true"))
    {
        connection.Open();

        var transaction = connection.BeginTransaction();

        var transactionContext = GetTransactionContext(connection, transaction);

        // the following line throws an exception
        var sqlFileStream = new SqlFileStream(path, transactionContext, FileAccess.Read);

        var buffer = new byte[4];
        sqlFileStream.Read(buffer, 0, 4);

        data = BitConverter.ToInt32(buffer, 0);
    }
}

private static byte[] GetTransactionContext(SqlConnection connection, SqlTransaction transaction)
{
    using (var cmd = connection.CreateCommand())
    {
        const string myGetTxContextQuery = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";
        cmd.CommandText = myGetTxContextQuery;
        cmd.CommandTimeout = 60;
        cmd.CommandType = CommandType.Text;
        cmd.Transaction = transaction;
        return (byte[])cmd.ExecuteScalar();
    }
}

尝试构造SqlFileStream实例时抛出异常:

System.ComponentModel.Win32Exception 发生 Message="不支持该请求" 源="系统.数据" 错误代码=-2147467259 NativeErrorCode=50

有人知道我做错了什么吗?

【问题讨论】:

  • 对答案 1 的响应:不能将“context connection=true”用于模拟 (blogs.msdn.com/dataaccess/archive/2006/01/25/517495.aspx)。打开连接时出现 InvalidOperationException 失败(“在此上下文中不允许数据访问。上下文是未标记为 DataAccessKind.Read 或 SystemDataAccessKind.Read 的函数或方法,是从 Table Valued 的 FillRow 方法获取数据的回调函数,或者是 UDT 验证方法”)。如果我更改连接字符串以指定具有集成安全性的数据源,则会收到与以前相同的错误。

标签: c# sql-server filestream sqlclr


【解决方案1】:

您需要通过冒充执行查询的人来提升权限。

这是一个很好的模拟示例:

http://drowningintechnicaldebt.com/blogs/shawnweisfeld/archive/2009/06/11/sql-clr-query-the-file-system-to-get-a-list-of-folders.aspx

【讨论】:

    【解决方案2】:

    creating the assembly in SQL Server 时你使用了WITH PERMISSION_SET = EXTERNAL_ACCESS 吗?默认情况下 CREATE ASSEMBLY 使用 SAFE 权限集,其中doesn't include FileIOPermissions,required 由 SqlFileStream 构造函数。

    【讨论】:

    • 是的,程序集正在使用 EXTERNAL_ACCESS 权限。不幸的是,我没有时间进一步调查,但计划很快就会这样做。我会报告我取得的任何进展。
    【解决方案3】:

    我无法使用 SqlFileStream 直接从 CLR 中访问文件流(由于上述问题)。我最终采用的解决方案是使用 SQL 存储过程来获取我需要的文件流数据的子集。虽然这在某些情况下并不是特别有效,但对我的应用来说已经足够了

        CREATE PROC ReadFromFilestream
        (
            @pfilestreamGUID    UNIQUEIDENTIFIER,
            @pOffsetIntoData    INT,
            @pLengthOfData      INT,
            @pData              VARBINARY(MAX) OUTPUT
        )
        AS
        BEGIN;
            SELECT @pData  = SUBSTRING(ValueData, @pOffsetIntoData, @pLengthOfData)
              FROM [MESL].DataStream
             WHERE DataStreamGUID = @pfilestreamGUID;
        END;
    

    【讨论】:

      猜你喜欢
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多