对逻辑进行编程,以更新和获取数据到同一存储过程/从同一存储过程获取数据
本文关键字:数据 获取 存储过程 更新 编程 | 更新日期: 2023-09-27 18:00:03
我正在这个项目上创建一个每 20 秒创建一次线程的 Windows 服务。此服务从存储过程中获取文本和数字,并将 SMS 发送到这些数字,并在线程的每一端将结果返回到存储过程。
在该逻辑中,我必须多次调用存储过程,因此我要做的是同时获取和更新数据。代码流是这样的:这是在服务启动时调用的函数。
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
( 声明为类属性并且它是静态的,现在每个线程将在本地更新到一个 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;
}