国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

用c#讀取并分析sql2005日志

2019-11-17 03:03:30
字體:
來源:轉載
供稿:網友
用c#讀取并分析sql2005日志

用過logExplorer的朋友都會被他強悍的功能吸引,我寫過一篇詳細的操作文檔可以參考http://blog.csdn.net/jinjazz/archive/2008/05/19/2459692.aspx我們可以自己用開發工具來實現sql日志的讀取,這個應用還是很酷的,具體思路1、首先要了解一個沒有公開的系統函數::fn_dblog,他可以讀取sql日志,并返回二進制的行數據2、然后要了解sql的二進制數據是如何存儲的,這個可以參考我的blog文章http://blog.csdn.net/jinjazz/archive/2008/08/07/2783872.aspx3、用自己擅長的開發工具來分析數據,得到我們需要的信息我用c#寫了一個測試樣例,分析了int,char,datetime和varchar的日志情況而且沒有考慮null和空字符串的保存,希望感興趣的朋友能和我一起交流打造屬于自己的日志分析工具詳細的試驗步驟以及代碼如下:1、首先建立sqlserver的測試環境,我用的sql2005,這個過程不能保證在之前的版本中運行以下sql語句會建立一個dbLogTest數據庫,并建立一張log_test表,然后插入3條數據之后把表清空

  1. usemaster
  2. go
  3. createdatabasedbLogTest
  4. go
  5. usedbLogTest
  6. go
  7. createtablelog_test(idint,codechar(10),namevarchar(20),datedatetime,memovarchar(100))
  8. insertintolog_testselect100,'id001','jinjazz',getdate(),'剪刀'
  9. insertintolog_testselect65549,'id002','游客',getdate()-1,'這家伙很懶,沒有設置昵稱'
  10. insertintolog_testselect-999,'id003','這家伙來自火星',getdate()-1000,'a'
  11. deletefromlog_test
  12. --usemaster
  13. --go
  14. --dropdatabasedbLogTest

2、我們最終的目的是要找到被我們刪掉的數據3、分析日志的c#代碼:我已經盡量詳細的寫了注釋

  1. usingSystem;
  2. usingSystem.Collections.Generic;
  3. usingSystem.Text;
  4. namespaceConsoleapplication21
  5. {
  6. classPRogram
  7. {
  8. ///<summary>
  9. ///分析sql2005日志,找回被delete的數據,引用請保留以下信息
  10. ///作者:jinjazz(csdn的剪刀)
  11. ///作者blog:http://blog.csdn.net/jinjazz
  12. ///</summary>
  13. ///<paramname="args"></param>
  14. staticvoidMain(string[]args)
  15. {
  16. using(System.Data.SqlClient.SqlConnectionconn=newSystem.Data.SqlClient.SqlConnection())
  17. {
  18. conn.ConnectionString="server=localhost;uid=sa;pwd=sqlgis;database=dbLogTest";
  19. conn.Open();
  20. using(System.Data.SqlClient.SqlCommandcommand=conn.CreateCommand())
  21. {
  22. //察看dbo.log_test對象的sql日志
  23. command.CommandText=@"SELECTallocunitname,Operation,[RowLogContents0]asr0,[RowLogContents1]asr1
  24. from::fn_dblog(null,null)
  25. whereallocunitnamelike'dbo.log_test%'and
  26. operationin('LOP_INSERT_ROWS','LOP_DELETE_ROWS')";
  27. System.Data.SqlClient.SqlDataReaderreader=command.ExecuteReader();
  28. //根據表字段的順序建立字段數組
  29. Datacolumn[]columns=newDatacolumn[]
  30. {
  31. newDatacolumn("id",System.Data.SqlDbType.Int),
  32. newDatacolumn("code",System.Data.SqlDbType.Char,10),
  33. newDatacolumn("name",System.Data.SqlDbType.VarChar),
  34. newDatacolumn("date",System.Data.SqlDbType.DateTime),
  35. newDatacolumn("memo",System.Data.SqlDbType.VarChar)
  36. };
  37. //循環讀取日志
  38. while(reader.Read())
  39. {
  40. byte[]data=(byte[])reader["r0"];
  41. try
  42. {
  43. //把二進制數據結構轉換為明文
  44. TranslateData(data,columns);
  45. Console.WriteLine("數據對象{1}的{0}操作:",reader["operation"],reader["allocunitname"]);
  46. foreach(Datacolumncincolumns)
  47. {
  48. Console.WriteLine("{0}={1}",c.Name,c.Value);
  49. }
  50. Console.WriteLine();
  51. }
  52. catch
  53. {
  54. //to-do...
  55. }
  56. }
  57. reader.Close();
  58. }
  59. conn.Close();
  60. }
  61. Console.WriteLine("************************日志分析完成");
  62. Console.ReadLine();
  63. }
  64. //自定義的column結構
  65. publicclassDatacolumn
  66. {
  67. publicstringName;
  68. publicSystem.Data.SqlDbTypeDataType;
  69. publicshortLength=-1;
  70. publicobjectValue=null;
  71. publicDatacolumn(stringname,System.Data.SqlDbTypetype)
  72. {
  73. Name=name;
  74. DataType=type;
  75. }
  76. publicDatacolumn(stringname,System.Data.SqlDbTypetype,shortlength)
  77. {
  78. Name=name;
  79. DataType=type;
  80. Length=length;
  81. }
  82. }
  83. ///<summary>
  84. ///sql二進制結構翻譯,這個比較關鍵,測試環境為sql2005,其他版本沒有測過。
  85. ///</summary>
  86. ///<paramname="data"></param>
  87. ///<paramname="columns"></param>
  88. staticvoidTranslateData(byte[]data,Datacolumn[]columns)
  89. {
  90. //我只根據示例寫了Char,DateTime,Int三種定長度字段和varchar一種不定長字段,其余的有興趣可以自己補充
  91. //這里沒有暫時沒有考慮Null和空字符串兩種情況,以后會補充。
  92. //引用請保留以下信息:
  93. //作者:jinjazz
  94. //sql的數據行二進制結構參考我的blog
  95. //http://blog.csdn.net/jinjazz/archive/2008/08/07/2783872.aspx
  96. //行數據從第5個字節開始
  97. shortindex=4;
  98. //先取定長字段
  99. foreach(Datacolumncincolumns)
  100. {
  101. switch(c.DataType)
  102. {
  103. caseSystem.Data.SqlDbType.Char:
  104. //讀取定長字符串,需要根據表結構指定長度
  105. c.Value=System.Text.Encoding.Default.GetString(data,index,c.Length);
  106. index+=c.Length;
  107. break;
  108. caseSystem.Data.SqlDbType.DateTime:
  109. //讀取datetime字段,sql為8字節保存
  110. System.DateTimedate=newDateTime(1900,1,1);
  111. //前四位1/300秒保存
  112. intsecond=BitConverter.ToInt32(data,index);
  113. date=date.AddSeconds(second/300);
  114. index+=4;
  115. //后四位1900-1-1的天數
  116. intdays=BitConverter.ToInt32(data,index);
  117. date=date.AddDays(days);
  118. index+=4;
  119. c.Value=date;
  120. break;
  121. caseSystem.Data.SqlDbType.Int:
  122. //讀取int字段,為4個字節保存
  123. c.Value=BitConverter.ToInt32(data,index);
  124. index+=4;
  125. break;
  126. default:
  127. //忽略不定長字段和其他不支持以及不愿意考慮的字段
  128. break;
  129. }
  130. }
  131. //跳過三個字節
  132. index+=3;
  133. //取變長字段的數量,保存兩個字節
  134. shortvarColumnCount=BitConverter.ToInt16(data,index);
  135. index+=2;
  136. //接下來,每兩個字節保存一個變長字段的結束位置,
  137. //所以第一個變長字段的開始位置可以算出來
  138. shortstartIndex=(short)(index+varColumnCount*2);
  139. //第一個變長字段的結束位置也可以算出來
  140. shortendIndex=BitConverter.ToInt16(data,index);
  141. //循環變長字段列表讀取數據
  142. foreach(Datacolumncincolumns)
  143. {
  144. switch(c.DataType)
  145. {
  146. caseSystem.Data.SqlDbType.VarChar:
  147. //根據開始和結束位置,可以算出來每個變長字段的值
  148. c.Value=System.Text.Encoding.Default.GetString(data,startIndex,endIndex-startIndex);
  149. //下一個變長字段的開始位置
  150. startIndex=endIndex;
  151. //獲取下一個變長字段的結束位置
  152. index+=2;
  153. endIndex=BitConverter.ToInt16(data,index);
  154. break;
  155. default:
  156. //忽略定長字段和其他不支持以及不愿意考慮的字段
  157. break;
  158. }
  159. }
  160. //獲取完畢
  161. }
  162. }
  163. }

4、更改你的sql連接字符串后運行以上代碼,會看到如下輸出信息:

  1. 數據對象dbo.log_test的LOP_INSERT_ROWS操作:
  2. id=100
  3. code=id001
  4. name=jinjazz
  5. date=2008-8-718:14:03
  6. memo=剪刀
  7. 數據對象dbo.log_test的LOP_INSERT_ROWS操作:
  8. id=65549
  9. code=id002
  10. name=游客
  11. date=2008-8-618:14:03
  12. memo=這家伙很懶,沒有設置昵稱
  13. 數據對象dbo.log_test的LOP_INSERT_ROWS操作:
  14. id=-999
  15. code=id003
  16. name=這家伙來自火星
  17. date=2005-11-1118:14:03
  18. memo=a
  19. 數據對象dbo.log_test的LOP_DELETE_ROWS操作:
  20. id=100
  21. code=
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 股票| 荥阳市| 行唐县| 天祝| 上思县| 信阳市| 建湖县| 改则县| 武陟县| 陕西省| 千阳县| 育儿| 乌兰察布市| 长岭县| 晋宁县| 牟定县| 辽宁省| 崇仁县| 抚远县| 安新县| 普洱| 古蔺县| 霍州市| 武功县| 顺平县| 霍邱县| 边坝县| 榆树市| 威远县| 于田县| 增城市| 铜川市| 鸡泽县| 五台县| 西乌珠穆沁旗| 辛集市| 石渠县| 德清县| 沈阳市| 鄂尔多斯市| 岢岚县|