我也来学着写写WINDOWS服务-解析xml抓取数据并插入数据库项目告一段落,快到一年时间开发了两个系统,一个客户已经在试用,一个进入客户测试阶段,中间突然被项目经理(更喜欢叫他W工)分派一个每隔两小时用windows服务去抓取客户提供的外网xml,解析该xml,然后将截取的节点字段值插入到已经建好相应结构的表中。并记录日志。
xml结构概要如下:
<?xml version="1.0" encoding="UTF-8"?><list> <info> <id>93ef7c7cccd2ecb13ed01dd6e30020b4136</id> <title>剔骨刀一握六年练过硬本领 女庖丁解牛割肉有拿手好戏</title> <posttime class="sql-timestamp">2015-05-25 06:38:20.0</posttime> <institution>浙江省物价局</institution> <url>http://dsb.66wz.com/html/2015-05/25/content_1822593.htm</url> <webName>温州都市报数字版</webName> <infotype>新闻</infotype> <summary>内容</summary> <fl>其他类</fl> </info> <info> ... </info> <info> ... </info>。。。</list>
1.首先,让我们新建一个解决方案,该解决方案中包含9个项目:
(1)由于需要操作的是Oracle数据库系统,所以在MSDN上找了个Oracle数据操作类库DatabaseLib和DatabaseLink直接拿来用,一个是数据库连接类,一个是数据库操作类,里面包含各种对数据库的操作;
其中,DatabaseLink主要包括以下三个文件:
DbLink.cs
using System.Data;namespace DataBaseLink{ /// <summary> /// DATA :2010-07-01 /// Author :虞健超(James.Yu) /// Describe :数据库连接对象 /// </summary> public class DbLink : IDbLink { public string ConnectionStr { get; set; } public DbLink(string connectStr) { ConnectionStr = connectStr; }#if MSSQL public IDbConnection CreateConnection() { return new System.Data.SqlClient.SqlConnection(ConnectionStr); } public IDataAdapter CreateAdapter(IDbCommand cmd) { return new System.Data.SqlClient.SqlDataAdapter((System.Data.SqlClient.SqlCommand)cmd); }#endif }}
IDbLink.cs
using System.Data;namespace DataBaseLink{ /// <summary> /// DATA :2010-07-01 /// Author :虞健超(James.Yu) /// Describe :连接创建对象借口 /// </summary> public interface IDbLink { /// <summary> /// 连接字符串 /// </summary> string ConnectionStr { get; set; } /// <summary> /// 创建连接 /// </summary> /// <returns>连接</returns> IDbConnection CreateConnection(); /// <summary> /// 创建Adapter /// </summary> /// <param name="cmd">cmd</param> /// <returns></returns> IDataAdapter CreateAdapter(IDbCommand cmd); }}
以及存储过程映射类DBStorePRocedureManager.cs
namespace DataBaseLink{ /// <summary> /// DATA :2010-07-01 /// Author :虞健超(James.Yu) /// Describe :存储过程接口,里面存储存储过程名,以及参数列表方便调用时反射 /// </summary> public interface IDbStoreProcedureManager { //存储过程映射,这里是名为SP_TestApply的存储过程 void SP_TestApply(string c1, int? c2); }}
在这个程序中主要用到前两个类;
而对于数据库操作主要用到以下代码:
OracleDBHelper.cs中的
public static int ExecuteNonQuery(string sql, OracleParameter[] para, CommandType cmdType) { int rows = -1; using (OracleConnection conn = new OracleConnection(ConnectionString)) { OracleCommand cmd = new OracleCommand(sql, conn); if (para != null) { cmd.Parameters.AddRange(para); } cmd.CommandType = cmdType; conn.Open(); rows = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); conn.Close(); } return rows; }
public override unsafe int ExecuteNonQuery() { string[] ppOpoPrmRefCtx = null; IntPtr[] pOpoPrmValCtx = null; OracleParameter parameter; int num7; int num8; IntPtr zero = IntPtr.Zero; IntPtr opsSubscrCtx = IntPtr.Zero; int isSubscrRegistered = 0; OracleDependency dep = null; int bQueryBasedNTFNRegistration = 0; int bchgNTFNExcludeRowidInfo = 0; long num4 = 0L; int errCode = 0; int prmCnt = 0; bool flag = false; int bFromPool = 0; CmdTimeoutCtx state = null; Timer timer = null; if (OraTrace.m_TraceLevel != 0) { OraTrace.Trace(1, new string[] { " (ENTRY) OracleCommand::ExecuteNonQuery()\n" }); } if (this.m_connection == null) { throw new InvalidOperationException(); } if (this.m_cmdTxtModified && ((this.m_commandText == null) || (this.m_commandText.Length == 0))) { throw new InvalidOperationException(OpoErrResManager.GetErrorMesg(ErrRes.ODP_INVALID_VALUE, new string[] { "OracleCommand.CommandText" })); } if (this.m_xmlCommandType != OracleXmlCommandType.None) { if (OracleXmlCommandType.Query == this.m_xmlCommandType) { this.ExecuteXmlQuery(false); return -1; } return this.ExecuteXmlSave(); } this.CheckConStatus(); if (this.m_cmdTxtModified || (this.m_commandType == System.Data.CommandType.StoredProcedure)) { if (this.m_commandType == System.Data.CommandType.Text) { this.m_selectStmt = isSelectStatement(this.m_commandText); this.m_pooledCmdText = this.m_commandText; } else if (this.m_commandType == System.Data.CommandType.TableDirect) { this.m_selectStmt = true; this.m_pooledCmdText = "Select * from " + this.m_commandText; } else if (this.m_commandType == System.Data.CommandType.StoredProcedure) { this.BuildCommandText(); this.m_selectStmt = false; this.m_utf8CmdText = null; this.m_addParam = true; } UTF8CommandText text = UTF8CommandText.m_pooler.Get(this.m_connection.m_internalConStr, this.m_pooledCmdText) as UTF8CommandText; if ((text != null) && (text.m_utf8CmdText != IntPtr.Zero)) { this.m_utf8CmdText = text; this.m_addParam = this.m_utf8CmdText.m_addParam; this.m_parsed = this.m_utf8CmdText.m_parsed; bFromPool = 1; } if (!this.m_parsed && (this.m_commandType == System.Data.CommandType.Text)) { this.ParseCommandText(); } this.m_cmdTxtModified = false; } if (this.m_bindByName && (this.m_commandType != System.Data.CommandType.StoredProcedure)) { flag = true; } if (((this.m_NTFNReq != null) && this.m_NTFNAutoEnlist) && (!this.m_connection.m_contextConnection && (OracleNotificationRequest.s_idTable[this.m_NTFNReq.Id] != null))) { opsSubscrCtx = OracleNotificationRequest.PopulateChgNTFNSubscrCtx(this, this.m_addRowid, out dep); if ((dep != null) && dep.m_bIsRegistered) { isSubscrRegistered = 1; } if (dep != null) { if (dep.m_OracleRowidInfo == OracleRowidInfo.Exclude) {