2011-09-14 40 views
2

我已經在Windows 7上的SQL Server Express 2008 SP1(版本6.1生成7601:Service Pack 1中)和Visual Studio 2010sqlFileStream System.ComponentModel.Win32Exception:請求不被支持

我試圖創建一個存儲過程CLR,用於使用以下代碼將文件插入到文件流中。

using System; 
using System.Data; 
using System.Data.SqlClient; 
using System.Data.SqlTypes; 
using Microsoft.SqlServer.Server; 
using System.IO; 
using System.Security.Principal; 

public partial class StoredProcedures 
{ 
    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static void sp_fileController(String friendlyName, String filePath) 
{ 
    SqlParameter fDataParam = new System.Data.SqlClient.SqlParameter("@fData", SqlDbType.VarBinary, -1); 
    SqlParameter fNameParam = new System.Data.SqlClient.SqlParameter("@fName", SqlDbType.NVarChar, 300); 

    WindowsIdentity newId = SqlContext.WindowsIdentity; 
    WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 

    try 
    { 
     string cs = @"Server=[myservername];Integrated Security=true"; 
     using (SqlConnection con = new SqlConnection(cs)) 
     { 
      con.Open(); 
      SqlTransaction objSqlTran = con.BeginTransaction(); 

      //string sql = "INSERT INTO fileStreamTest VALUES ((Cast('' As varbinary(Max))), @fName, default); Select fData.PathName() As Path From fileStreamTest Where fId = SCOPE_IDENTITY()";//OUTPUT inserted.fid 
      SqlCommand insertFileCommand = con.CreateCommand(); 

      insertFileCommand.Transaction = objSqlTran; 

      insertFileCommand.CommandText = "INSERT INTO fileStreamTest.dbo.fileStreamTest (RowGuid, fData) VALUES (@FileID, CAST ('' as varbinary(max)))"; 

      Guid newFileID = Guid.NewGuid(); 

      insertFileCommand.Parameters.Add("@FileID", SqlDbType.UniqueIdentifier).Value = newFileID; 

      insertFileCommand.ExecuteNonQuery(); 

      SqlCommand getPathAndTokenCommand = con.CreateCommand(); 

      getPathAndTokenCommand.Transaction = objSqlTran; 

      getPathAndTokenCommand.CommandText = 
       "SELECT fData.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() " + 
       "FROM fileStreamTest.dbo.fileStreamTest " + 
       "WHERE rowGuid = @FileID"; 

      getPathAndTokenCommand.Parameters.Add("@FileID", SqlDbType.UniqueIdentifier).Value = newFileID; 

      SqlDataReader tokenReader = getPathAndTokenCommand.ExecuteReader(CommandBehavior.SingleRow); 

      tokenReader.Read(); 

      SqlString filePathName = tokenReader.GetSqlString(0); 

      SqlBinary fileToken = tokenReader.GetSqlBinary(1); 

      tokenReader.Close(); 

      SqlFileStream sqlFile = new SqlFileStream(filePathName.Value, fileToken.Value, System.IO.FileAccess.ReadWrite); 
      sqlFile.Close(); 

      objSqlTran.Rollback(); 
      //objSqlTran.Commit(); 
      con.Close(); 

     } 
    } 
    finally 
    { 
     impersonatedUser.Undo(); 
    } 
} 
}; 

但是當它到達線路:

SqlFileStream sqlFile = new SqlFileStream(filePathName.Value, fileToken.Value, System.IO.FileAccess.ReadWrite); 

我得到:

用戶定義的例程或聚合 「sp_fileController」 的執行過程中出現

一個.NET Framework錯誤:

System.ComponentModel.Win32Exception: The request is not supported 
System.ComponentModel.Win32Exception: 
    at System.Data.SqlTypes.SqlFileStream.OpenSqlFileStream(String path, Byte[] transactionContext, FileAccess access, FileOptions options, Int64 allocationSize) 
    at System.Data.SqlTypes.SqlFileStream..ctor(String path, Byte[] transactionContext, FileAccess access, FileOptions options, Int64 allocationSize) 
    at System.Data.SqlTypes.SqlFileStream..ctor(String path, Byte[] transactionContext, FileAccess access) 
    at StoredProcedures.sp_fileController(String friendlyName, String filePath) 

誰能告訴我如何解決這個問題?簡單地說,我無法用sql 2008 express版本以這種方式執行代碼?

回答

0

儘管聽起來微軟奇刻意封鎖使用SQL CLR組件內的SqlFileStream類用途(即使您授予EXTERNAL_ACCESS或聲明的組合件UNSAFE),你可以在Microsoft Connect issue 768308讀取。

但是,您可以通過SqlBytes類型(在blog post上找到一個非常好的技巧)以流的形式訪問FILESTREAM ..至少只讀使用,我從來沒有試過寫過。

我複製過去的情況下,博客消失的代碼(在略有改善版本,妥善處置的對象):

using System; 
using System.IO; 
using System.Data.SqlTypes; 
using Microsoft.SqlServer.Server; 
using System.Security.Cryptography; 

public partial class UserDefinedFunctions 
{ 
    [Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true, SystemDataAccess = SystemDataAccessKind.None)] 
    public static SqlBinary Hash(SqlBytes source, SqlString hashAlgorithmName) 
    { 
     if (Source.IsNull) 
     { 
      return null; 
     } 

     using (HashAlgorithm ha = GetHashAlgotithm(hashAlgorithmName.Value)) 
     using (Stream stream = Source.Stream) 
     { 
      return new SqlBinary(ha.ComputeHash(source.Stream)); 
     } 
    } 
} 

我可以證實這肯定適用於只讀訪問。我從來沒有嘗試寫入權限(我正在從外部C#Windows服務或Web應用程序寫入FILESTREAM數據)。

+0

我知道這是一個老問題,無論如何,我試圖找到無用的'System.ComponentModel.Win32Exception:請求不支持'的解決方案時偶然發現了錯誤消息,並且後來發現解決方案中描述的解決方案。 – Fulvio