2016-11-11 159 views
0

我有两个CLR函数用于压缩/解压缩NVARCHAR数据。SQL CLR函数解压缩GZip数据

[SqlFunction(IsDeterministic = true, IsPrecise = true, DataAccess = DataAccessKind.None)] 
public static SqlBytes ufn_GZipCompress(SqlString input) { 
    if (input.IsNull || input.Value.Length == 0) 
     return SqlBytes.Null; 

    using (MemoryStream msInput = new MemoryStream(input.GetUnicodeBytes())) { 
     using (MemoryStream msOutput = new MemoryStream()) { 
      using (GZipStream deflateStream = new GZipStream(msOutput, CompressionMode.Compress, true)) { 
       byte[] buffer = new byte[32768]; 
       int read; 
       while ((read = msInput.Read(buffer, 0, buffer.Length)) > 0) 
        msOutput.Write(buffer, 0, read); 
      } 

      return new SqlBytes(msOutput.ToArray()); 
     } 
    } 
} 

[SqlFunction(IsDeterministic = true, IsPrecise = true, DataAccess = DataAccessKind.None)] 
public static SqlString ufn_GZipDecompress(SqlBytes input) { 
    if (input.IsNull || input.IsNull) 
     return SqlString.Null; 

    byte[] buf = new byte[32768]; 

    using (MemoryStream msOutput = new MemoryStream()) { 
     using (GZipStream deflateStream = new GZipStream(input.Stream, CompressionMode.Decompress, true)) { 
      int bytesRead; 
      while ((bytesRead = deflateStream.Read(buf, 0, 32768)) > 0) 
       msOutput.Write(buf, 0, bytesRead); 
     } 

     return new SqlString(Encoding.UTF8.GetString(msOutput.ToArray())); 
    } 
} 

问题是,当我尝试解压缩的二进制数据,我不明白的是,预计输出,例如:

SELECT dbo.[ufn_GZipDecompress](dbo.[ufn_GZipCompress](N'Hello World')) 

返回

H 

回答

0

我正在工作在某些时候加密CLRs并记住类似的东西,结果是编码问题。 sql的默认SQL_Latin1_General_CP1_CI_ASWindows-1252编码不是UTF-8

如果这将是您的GetUnicodeBytes以及您返回的编码问题,我不积极。你应该测试,以确保input.GetUnicodeBytes()给你想要的结果,我通过重新编译和抛出自定义异常与数据,但我相信别人有其他方法。

然后为你解压缩,你可以尝试这样的:

Encoding enc = Encoding.GetCoding(1252); 
ecn.GetString(yourbytearray) 
+1

这当然看起来像一个编码问题。我的猜测是'GetUnicodeBytes()'提供UTF16字节,这意味着'UTF8.GetString'将把第一个字符的高位字节解释为空终止符。 –