对逻辑进行编程,以更新和获取数据到同一存储过程/从同一存储过程获取数据

本文关键字:数据 获取 存储过程 更新 编程 | 更新日期: 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;
}