0

I have a method that inserts a new record after checking whether it already exists or not.

Here is my method:

protected void btn_save_Click(object sender, EventArgs e)
{
    string MobileNo = "";
    string replaceValue = txt_mobile.Text.Replace(Environment.NewLine, "$");

    string[] values = replaceValue.Split('$');
    int uCnt = 0;
    int sCnt = 0;

    foreach (string item in values)
    {
        SaveRecord(item.Trim(),out MobileNo,out uCnt,out sCnt);
    }

    txt_mobile.Text = string.Empty;

    if(uCnt > 0)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "BulkSMS System", "alert('Mobile No(s) : "+MobileNo.TrimEnd(',')+" Already Exist');", true);
    }

    if(sCnt > 0)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "BulkSMS System", "alert('" + sCnt + " Record(s) Inserted Successfully');", true);
    }

    Get_Data();
}

public void SaveRecord(string value, out string MobileNo, out int uCnt, out int sCnt)
{
    uCnt = 0; //every time initialized to 0
    sCnt = 0; //every time initialized to 0 
    MobileNo = "";

    try
    {
        DataTable dt = new DataTable();
        var dot = Regex.Match(value, @"\+?[0-9]{10}");

        if (dot.Success)
        {
            string str = "SELECT TOP 1 [ID],[MobileNo] FROM[dbo].[whitelistdata]";
            str += " WHERE [UserID] = '" + Convert.ToInt32(ddl_users.SelectedValue.ToString()) + "' AND [SenderId] = '" + Convert.ToInt32(ddl_senders.SelectedValue.ToString()) + "' AND [MobileNo] = '" + value + "'";
            dt = obj.Get_Data_Table_From_Str(str);

            if (dt.Rows.Count > 0)
            {
                uCnt++;
                MobileNo += value + ",";
            }
            else
            {
                string str1 = "INSERT INTO [dbo].[whitelistdata]([UserID],[SenderId],[KeywordID],[MobileNo])";
                str1 += "VALUES (" + Convert.ToInt32(ddl_users.SelectedValue.ToString()) + "," + Convert.ToInt32(ddl_senders.SelectedValue.ToString()) + ",1," + value + ")";
                obj.Execute_Query(str1);
                sCnt++;
            }
        }
    }
    catch (Exception ex)
    {
        CommonLogic.SendMailOnError(ex);
        ClientScript.RegisterStartupScript(this.GetType(), "BulkSMS System", "alert('" + ex.Message.ToString() + "');", true);
    }
}

The problem is every time it's set to 0 when method has been called I want to prevent them when previous value is greater than 0.

Please help me guys..

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Gajjar Shalin
  • 95
  • 1
  • 11
  • what is previous value here? UserID, mobile? Also what is 'it'? Please edit, it will be easy. https://stackoverflow.com/questions/18373461/execute-insert-command-and-return-inserted-id-in-sql – Incredible Mar 13 '19 at 12:23
  • mobile no from database. – Gajjar Shalin Mar 13 '19 at 12:25
  • [SQL Injection alert](http://msdn.microsoft.com/en-us/library/ms161953%28v=sql.105%29.aspx) - you should **not** concatenate together your SQL statements - use **parametrized queries** instead to avoid SQL injection - check out [Little Bobby Tables](http://bobby-tables.com/) – marc_s Jun 08 '19 at 10:49

2 Answers2

1

Please first identify which combination check-in database.

if UserID AND SenderId combination Match Then

 string str = "SELECT TOP 1 [ID],[MobileNo] FROM[dbo].[whitelistdata]";
 str += " WHERE [UserID] = '" + Convert.ToInt32(ddl_users.SelectedValue.ToString()) + "' AND [SenderId] = '" + Convert.ToInt32(ddl_senders.SelectedValue.ToString()) + "'";

if check the only UserID Match Then

 string str = "SELECT TOP 1 [ID],[MobileNo] FROM[dbo].[whitelistdata]";
 str += " WHERE [UserID] = '" + 
     Convert.ToInt32(ddl_users.SelectedValue.ToString()) +"'";

if UserID OR SenderId combination Match Then

 string str = "SELECT TOP 1 [ID],[MobileNo] FROM[dbo].[whitelistdata]";
 str += " WHERE [UserID] = '" + Convert.ToInt32(ddl_users.SelectedValue.ToString()) + "' OR [SenderId] = '" + Convert.ToInt32(ddl_senders.SelectedValue.ToString()) + "'";

if UserID AND SenderId AND MobileNo combination Match Then

string str = "SELECT TOP 1 [ID],[MobileNo] FROM[dbo].[whitelistdata]";
str += " WHERE [UserID] = '" + Convert.ToInt32(ddl_users.SelectedValue.ToString()) + "' AND [SenderId] = '" + Convert.ToInt32(ddl_senders.SelectedValue.ToString()) + "' AND [MobileNo] = '" + value + "'";
Hemang A
  • 1,012
  • 1
  • 5
  • 16
1

You need to use ref rather than out if you want to keep this design1. That means that the method can assume that the variables are already initialised and you're not forced to re-initialise them within the method:

public void SaveRecord(string value,out string MobileNo,ref int uCnt,ref int sCnt)
{
    //uCnt = 0; //initialized by caller
    //sCnt = 0; //initialized by caller
    MobileNo = ""; //?
   ....

And at the call site:

SaveRecord(item.Trim(),out MobileNo,ref uCnt,ref sCnt);

You'll also want to do something about MobileNo too if you expect that to accumulate values rather than be over-written each time through the loop. Maybe make it a StringBuilder instead that you just pass normally (no ref or out) and let the SaveRecord method append to. out is definitely wrong for it.


1Many people would frown at a method that clearly wants to return values being declared void and making all returns via ref/out.

Something like:

public bool SaveRecord(string value)
{
   ...

Returning true for a new record, false for an existing record. I'd probably take out the exception handling from there and let the exception propagate higher before it's handled. Then the call site would be:

if(SaveRecord(item.Trim()))
{
   sCnt++;
}
else
{
   uCnt++;
   MobileNo += item.Trim + ","
}
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448