SQL 解压缩 GZip 数据的 CLR 函数
SQL CLR Function to decompress GZip data
我有两个用于 compress/decompress NVARCHAR 数据的 CLR 函数。
[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'))
Returns
H
我曾在某个时候从事加密 CLR 工作,记得类似的事情,结果证明是编码问题。 sql 的默认 SQL_Latin1_General_CP1_CI_AS
是 Windows-1252
编码而不是 UTF-8
!
我不确定这是否会成为您的 GetUnicodeBytes 以及您返回的编码的问题。你应该测试以确保 input.GetUnicodeBytes()
给你想要的结果,我通过重新编译并抛出数据的自定义异常来做到这一点,但我相信其他人有其他方法。
然后对于你的解压缩,你可以尝试像这样的东西:
Encoding enc = Encoding.GetCoding(1252);
ecn.GetString(yourbytearray)
我有两个用于 compress/decompress NVARCHAR 数据的 CLR 函数。
[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'))
Returns
H
我曾在某个时候从事加密 CLR 工作,记得类似的事情,结果证明是编码问题。 sql 的默认 SQL_Latin1_General_CP1_CI_AS
是 Windows-1252
编码而不是 UTF-8
!
我不确定这是否会成为您的 GetUnicodeBytes 以及您返回的编码的问题。你应该测试以确保 input.GetUnicodeBytes()
给你想要的结果,我通过重新编译并抛出数据的自定义异常来做到这一点,但我相信其他人有其他方法。
然后对于你的解压缩,你可以尝试像这样的东西:
Encoding enc = Encoding.GetCoding(1252);
ecn.GetString(yourbytearray)