2009-09-01 9 views
2

J'essaie d'accéder à un flux de fichiers Sql à partir d'une procédure stockée CLR. J'ai mis en place une base de données très simple avec une seule table qui inclut une colonne filestream. Je peux lire avec succès à partir du flux de fichiers en utilisant une application de console simple. Voici quelques exemples de code pour le proc qui échoue:Accès à Sql FILESTREAM à partir d'une procédure stockée CLR

[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(); 
    } 
} 

Une exception est levée lors d'une tentative de construire l'instance SqlFileStream:

System.ComponentModel.Win32Exception produite lors Message = "La demande est pas pris en charge" Source = "System.Data" ErrorCode = -2147467259 NativeErrorCode = 50

Quelqu'un sait ce que je fais mal?

+0

Réponse à la réponse 1: Ne peut pas utiliser « Connexion contexte = true » avec usurpation d'identité (http://blogs.msdn.com/dataaccess /archive/2006/01/25/517495.aspx). Il a échoué avec InvalidOperationException lors de l'ouverture de la connexion ("L'accès aux données n'est pas autorisé dans ce contexte.) Le contexte est une fonction ou une méthode non marquée avec DataAccessKind.Read ou SystemDataAccessKind.Read, est un rappel pour obtenir des données de la méthode FillRow d'une table. Fonction, ou est une méthode de validation UDT "). Si je change la chaîne de connexion pour spécifier la source de données avec la sécurité intégrée, j'obtiens la même erreur que j'avais auparavant. – pete757

Répondre

0

Je ne pouvais pas utiliser SqlFileStream pour accéder aux flux de fichiers directement depuis le CLR (en raison des problèmes identifiés ci-dessus). La solution que j'ai finalement adoptée consistait à utiliser une procédure stockée SQL pour obtenir le sous-ensemble de données de flux de fichiers dont j'avais besoin. Bien que ce ne soit pas particulièrement efficace dans certains scénarios, il suffisait pour mon application

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; 
0

Avez-vous utilisé WITH PERMISSION_SET = EXTERNAL_ACCESS quand creating the assembly in SQL Server? Par défaut, CREATE ASSEMBLY utilise le jeu d'autorisations SAFE, qui est doesn't include FileIOPermissions, required par le constructeur SqlFileStream.

+0

Oui, l'assembly utilise l'autorisation EXTERNAL_ACCESS. Malheureusement, je n'ai pas eu le temps d'enquêter plus avant, mais je prévois de le faire bientôt. Je rapporterai avec tout progrès que je fais. – pete757

Questions connexes