更新和获取数据的程序逻辑 to/from 相同的存储过程
Program logic to Update and Get data to/from same stored procedure
我正在这个项目上创建一个每 20 秒创建一个线程的 Windows 服务。该服务从存储过程中获取文本和数字并将 SMS 发送到这些号码,并且在线程的每一端它 returns 结果到存储过程。
按照这个逻辑,我必须多次调用存储过程,所以我想做的是同时获取和更新数据。代码流程是这样的:这是调用onStart of service的函数。
public void Prepare(object state)
{
DataTable _dt = new DataTable();
DataTable _dt_sms_result = new DataTable();
_dt = GetInfo();
if (_dt != null)
{
_dt_sms_result.Columns.Add("sms_id", typeof(int));
_dt_sms_result.Columns.Add("send_time", typeof(DateTime));
_dt_sms_result.Columns.Add("result", typeof(string));
foreach (DataRow dr in _dt.Rows)
{
bool status = sendMsg(dr["smsid"].ToString(), dr["number"].ToString(), dr["messagetxt"].ToString(), dr["from"].ToString(), dr["to"].ToString());
Thread.Sleep(1000);
DataRow lvlrow = _dt_sms_result.NewRow();
lvlrow["sms_id"] = dr["sms_id"];
lvlrow["send_time"] = DateTime.Now;
if (status)
lvlrow["result"] = "Message Sent";
else
lvlrow["result"] = "Sending Failed";
_dt_sms_result.Rows.Add(lvlrow);
}//end foreach
PushInfo(_dt_sms_result);
}
GetInfo()
的代码:
public DataTable GetInfo()
{
cmd.CommandText = "StoreProc_511";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@username", "******");
cmd.Parameters.AddWithValue("@authcode", "******");
DataTable dt = new DataTable();
try
{
Connect();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
}
catch (SqlException se)
{
MyLog.Write(new LogPacket(se, DateTime.Now));
return null;
}
finally
{
Disconnect();
}
return dt;
}
PushInfo()
的代码:
public void PushInfo(DataTable dt_sms_result)
{
int res = -1;
cmd.CommandText = "StoreProc_511";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@username", "*****");
cmd.Parameters.AddWithValue("@authcode", "*****");
SqlParameter tvpParam = cmd.Parameters.AddWithValue("@sms_result", dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;
try
{
Connect();
res = cmd.ExecuteNonQuery();
}
catch (SqlException se)
{
MyLog.Write(new LogPacket(se, DateTime.Now));
Disconnect();
}
finally
{
Disconnect();
}
}
到目前为止,我的想法是将 _dt_sms_result
传递给 GetInfo()
并删除 PushInfo()
,因为我们只会进行一次调用。并添加
SqlParameter tvpParam = cmd.Parameters.AddWithValue("@sms_result", dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;
到GetInfo()
。
但我仍然对 GetInfo(with DT)
应该放在 Prepare()
方法上的逻辑感到困惑。
有人可以帮我解释这里的逻辑吗?谢谢!
基本上我解决这个问题的方法是,我将 datatable(_dt_sms_result
) 声明为 class 属性 并且它是静态的,现在每个线程都会更新为一个datatable(_dt_sms_result
) 在本地,因此当在 20 秒后创建新线程并调用 GetInfo()
时,它还会将 _dt_sms_result
作为参数发送到存储过程。此调用将同时获取号码、文本和其他信息并保存到数据表中。为了处理此调用期间的数据丢失和死锁,我已锁定此数据表,直到新数据表被存储过程恢复。
更改了 GetInfo()
的代码:
public DataTable GetInfo()
{
DataTable dt = new DataTable();
cmd.CommandText = "StoreProc_511";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@username", "*****");
cmd.Parameters.AddWithValue("@authcode", "*****");
lock (_dt_sms_result) {
SqlParameter tvpParam = cmd.Parameters.AddWithValue("@dt_sms_res", _dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;
try
{
Connect();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
_dt_sms_result.Rows.Clear();
}
catch (SqlException se)
{
MyLog.Write(new LogPacket(se, DateTime.Now));
}
finally
{
Disconnect();
}
}
return dt;
}
我正在这个项目上创建一个每 20 秒创建一个线程的 Windows 服务。该服务从存储过程中获取文本和数字并将 SMS 发送到这些号码,并且在线程的每一端它 returns 结果到存储过程。
按照这个逻辑,我必须多次调用存储过程,所以我想做的是同时获取和更新数据。代码流程是这样的:这是调用onStart of service的函数。
public void Prepare(object state)
{
DataTable _dt = new DataTable();
DataTable _dt_sms_result = new DataTable();
_dt = GetInfo();
if (_dt != null)
{
_dt_sms_result.Columns.Add("sms_id", typeof(int));
_dt_sms_result.Columns.Add("send_time", typeof(DateTime));
_dt_sms_result.Columns.Add("result", typeof(string));
foreach (DataRow dr in _dt.Rows)
{
bool status = sendMsg(dr["smsid"].ToString(), dr["number"].ToString(), dr["messagetxt"].ToString(), dr["from"].ToString(), dr["to"].ToString());
Thread.Sleep(1000);
DataRow lvlrow = _dt_sms_result.NewRow();
lvlrow["sms_id"] = dr["sms_id"];
lvlrow["send_time"] = DateTime.Now;
if (status)
lvlrow["result"] = "Message Sent";
else
lvlrow["result"] = "Sending Failed";
_dt_sms_result.Rows.Add(lvlrow);
}//end foreach
PushInfo(_dt_sms_result);
}
GetInfo()
的代码:
public DataTable GetInfo()
{
cmd.CommandText = "StoreProc_511";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@username", "******");
cmd.Parameters.AddWithValue("@authcode", "******");
DataTable dt = new DataTable();
try
{
Connect();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
}
catch (SqlException se)
{
MyLog.Write(new LogPacket(se, DateTime.Now));
return null;
}
finally
{
Disconnect();
}
return dt;
}
PushInfo()
的代码:
public void PushInfo(DataTable dt_sms_result)
{
int res = -1;
cmd.CommandText = "StoreProc_511";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@username", "*****");
cmd.Parameters.AddWithValue("@authcode", "*****");
SqlParameter tvpParam = cmd.Parameters.AddWithValue("@sms_result", dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;
try
{
Connect();
res = cmd.ExecuteNonQuery();
}
catch (SqlException se)
{
MyLog.Write(new LogPacket(se, DateTime.Now));
Disconnect();
}
finally
{
Disconnect();
}
}
到目前为止,我的想法是将 _dt_sms_result
传递给 GetInfo()
并删除 PushInfo()
,因为我们只会进行一次调用。并添加
SqlParameter tvpParam = cmd.Parameters.AddWithValue("@sms_result", dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;
到GetInfo()
。
但我仍然对 GetInfo(with DT)
应该放在 Prepare()
方法上的逻辑感到困惑。
有人可以帮我解释这里的逻辑吗?谢谢!
基本上我解决这个问题的方法是,我将 datatable(_dt_sms_result
) 声明为 class 属性 并且它是静态的,现在每个线程都会更新为一个datatable(_dt_sms_result
) 在本地,因此当在 20 秒后创建新线程并调用 GetInfo()
时,它还会将 _dt_sms_result
作为参数发送到存储过程。此调用将同时获取号码、文本和其他信息并保存到数据表中。为了处理此调用期间的数据丢失和死锁,我已锁定此数据表,直到新数据表被存储过程恢复。
更改了 GetInfo()
的代码:
public DataTable GetInfo()
{
DataTable dt = new DataTable();
cmd.CommandText = "StoreProc_511";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@username", "*****");
cmd.Parameters.AddWithValue("@authcode", "*****");
lock (_dt_sms_result) {
SqlParameter tvpParam = cmd.Parameters.AddWithValue("@dt_sms_res", _dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;
try
{
Connect();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
_dt_sms_result.Rows.Clear();
}
catch (SqlException se)
{
MyLog.Write(new LogPacket(se, DateTime.Now));
}
finally
{
Disconnect();
}
}
return dt;
}