用过logExplorer的朋友都会被他强悍的功能吸引,我写过一篇详细的操作文档可以参考
http://blog.csdn.net/jinjazz/archive/2008/05/19/2459692.aspx
测试SQL脚本:
实现代码:
try
{
//把二进制数据结构转换为明文
TranslateData(data, columns);
Console.WriteLine("数据对象{1}的{0}操作:", reader["operation"], reader["allocunitname"]);
foreach (Datacolumn c in columns)
{
Console.WriteLine("{0} = {1}", c.Name, c.Value);
}
Console.WriteLine();
}
catch
{
//to-do...
}
}
reader.Close();
}
conn.Close();
}
Console.WriteLine("************************日志分析完成");
Console.ReadLine();
}
//自定义的column结构
public class Datacolumn
{
public string Name;
public System.Data.SqlDbType DataType;
public short Length = -1;
public object Value = null;
public Datacolumn(string name, System.Data.SqlDbType type)
{
Name = name;
DataType = type;
}
public Datacolumn(string name,System.Data.SqlDbType type,short length)
{
Name = name;
DataType = type;
Length = length;
}
}
/// <summary>
/// sql二进制结构翻译,这个比较关键,测试环境为sql2005,其他版本没有测过。
/// </summary>
/// <param name="data"></param>
/// <param name="columns"></param>
static void TranslateData(byte[] data, Datacolumn[] columns)
{
//我只根据示例写了 Char,DateTime,Int三种定长度字段和varchar一种不定长字段,其余的有兴趣可以自己补充
//这里没有暂时没有考虑Null和空字符串两种情况,以后会补充。
//引用请保留以下信息:
//作者:jinjazz
//sql的数据行二进制结构参考我的blog
//http://blog.csdn.net/jinjazz/archive/2008/08/07/2783872.aspx
//行数据从第5个字节开始
short index = 4;
//先取定长字段
foreach (Datacolumn c in columns)
{
switch (c.DataType)
{
case System.Data.SqlDbType.Char:
//读取定长字符串,需要根据表结构指定长度
c.Value = System.Text.Encoding.Default.GetString(data,index,c.Length);
index += c.Length;
break;
case System.Data.SqlDbType.DateTime:
// 读取datetime字段,sql为8字节保存
System.DateTime date = new DateTime(1900, 1, 1);
// 前四位1/300秒保存
int second = BitConverter.ToInt32(data, index);
date = date.AddSeconds(second/300);
index += 4;
// 后四位1900-1-1的天数
int days = BitConverter.ToInt32(data, index);
date=date.AddDays(days);
index += 4;
c.Value = date;
break;
case System.Data.SqlDbType.Int:
//读取int字段,为4个字节保存
c.Value = BitConverter.ToInt32(data, index);
index += 4;
break;
default:
//忽略不定长字段和其他不支持以及不愿意考虑的字段
break;
}
}
//跳过三个字节
index += 3;
//取变长字段的数量,保存两个字节
short varColumnCount = BitConverter.ToInt16(data, index);
index += 2;
//接下来,每两个字节保存一个变长字段的结束位置,
//所以第一个变长字段的开始位置可以算出来
short startIndex =(short)( index + varColumnCount * 2);
//第一个变长字段的结束位置也可以算出来
short endIndex = BitConverter.ToInt16(data, index);
//循环变长字段列表读取数据
foreach (Datacolumn c in columns)
{
switch (c.DataType)
{
case System.Data.SqlDbType.VarChar:
// 根据开始和结束位置,可以算出来每个变长字段的值
c.Value =System.Text.Encoding.Default.GetString(data, startIndex, endIndex - startIndex);
// 下一个变长字段的开始位置
startIndex = endIndex;
// 获取下一个变长字段的结束位置
index += 2;
endIndex = BitConverter.ToInt16(data, index);
break;
default:
//忽略定长字段和其他不支持以及不愿意考虑的字段
break;
}
}
//获取完毕
}
}
}