2016-11-11 6 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

Я работал на CLR шифрования в какой-то момент и вспомнить что-то похожее на это, и это оказалось проблемой кодирования. sql по умолчанию SQL_Latin1_General_CP1_CI_AS is Windows-1252 закодировано NOT UTF-8!

Я не уверен, что это будет проблема с вашим GetUnicodeBytes, а также с вашей возвращенной кодировкой или нет. Вы должны проверить, чтобы убедиться, что input.GetUnicodeBytes() дает желаемый результат, я делаю это, перекомпилируя и выбрасывая пользовательские исключения с данными, но я уверен, что у других есть другие методы.

Тогда для вашего Распаковка вы можете попробовать что-то вроде:

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

Это, безусловно, выглядит как вопрос кодирования. Я предполагаю, что 'GetUnicodeBytes()' предоставляет байты UTF16, что означает, что 'UTF8.GetString' будет интерпретировать старший байт первого символа в качестве нулевого терминатора. –