I've got a question about SQL language which I couldn't find an answer for. I want SQL to automatically insert a number based off how much rows there are. Using an ASP.NET website I'm adding new rows and deleting rows. This means when I delete rows I want the table to automatically respond to that.
It is pretty hard to explain for me, so I already did some thinking ofcourse. I can fill it in using a C# code but when a row is deleted it ofcourse does not automatically change.
if (kisten < 4)
{
staple = 1;
}
else
{
if (staple1 >= 4)
{
staple = stapel2 + 1;
}
else
{
stapel = stapel2;
}
}
So what this means is that one staple contains 4 blocks. But I want if one row gets removed from the staple the first row of the second staple gets added to the first staple, so it gets value '1'.
Hope I am clear enough. If not, please don't hesitate to ask.
EDIT:
I am using SQL Server indeed. Here is a clear example of what I mean:
This is when everything is inserted using C# and as u can see it works fine.
This is when rows get deleted. As you can see the column 'Stapel' does not automatically change the number
What I want when rows get deleted
So after hours of trying I found a solution which works perfectly. Like so:
SqlCommand cmd11 = new SqlCommand("select count(kistid) from [dbo].[kist] where rij = '" + rij + "'", con);
int countrij = (Int32)cmd11.ExecuteScalar();
int procent = (4 / countrij * 100);
int hoeveel;
int hoeveel2 = (countrij % 4);
int hoeveel1;
if (hoeveel2 == 0)
{
hoeveel = (countrij / 4);
hoeveel1 = hoeveel;
for (int i = 0; i < hoeveel; i++)
{
SqlCommand sqlquery5 = new SqlCommand("UPDATE TOP (" + countrij + ") Kist SET Stapel ='" + hoeveel1 + "' WHERE Rij ='" + rij + "'");
sqlquery5.CommandType = System.Data.CommandType.Text;
sqlquery5.Connection = con;
sqlquery5.ExecuteNonQuery();
hoeveel1 = hoeveel1 - 1;
countrij = countrij - 4;
}
}
else
{
hoeveel = ((countrij - hoeveel2) / 4) + 1;
hoeveel1 = hoeveel;
for (int i = 0; i < hoeveel; i++)
{
SqlCommand sqlquery5 = new SqlCommand("UPDATE TOP (" + countrij + ") Kist SET Stapel ='" + hoeveel1 + "' WHERE Rij ='" + rij + "'");
sqlquery5.CommandType = System.Data.CommandType.Text;
sqlquery5.Connection = con;
sqlquery5.ExecuteNonQuery();
hoeveel1 = hoeveel1 - 1;
countrij = countrij - hoeveel2;
hoeveel2 = 4;
}
}
To automatically do something in a database when UPDATE, DELETE or INSERT command is executed for a given table you have to use CREATE TRIGGER to define a new trigger.
For more information just read about usage of triggers in your specific database server. For example for SQL Server you can read this.
Related
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..
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 + "'";
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 + ","
}
I want to insert into table for specific columns into table using select * from datatable.But it is giving me an array .. is there any way I can get the Insert work.
all I want to do is
Insert into table1 (id,name,status) select * from datatable
query += "Insert into " + tableName.ToLower() + "";
query += "(";
for (int i = 0; i < dt.Columns.Count; i++)
{
if (i != dt.Columns.Count - 1)
query += dt.Columns[i].ColumnName.ToLower() + ",";
else
query += dt.Columns[i].ColumnName.ToLower();
}
query += ")";
DataRow[] result = dt.Select();
query += "select * from " + result
You Can't use two sql Statements at once like that you have to separate them in two different objects or variables (It's sometimes allowed when you end each by a semicolon ; but not in your case )
try to get each cell value in the row
query += "Insert into " + tableName.ToLower() + "";
query += "(";
for (int i = 0; i < dt.Columns.Count; i++)
{
if (i != dt.Columns.Count - 1)
query += dt.Columns[i].ColumnName.ToLower() + ",";
else
query += dt.Columns[i].ColumnName.ToLower();
}
query += ")";
query += "values ( ";
string temQry=query;//you need it more than once
DataRow[] result = dt.Select();
for (int i = 0; i < dt.Rows.Count; i++){
for (int j = 0; j < dt.Columns.Count; j++){
if ((j+1)<dt.Columns.Count){
query += result[i].item(j) +"," ;
}
else {
query += result[i].item(j);}
}
query=temQry; //recover the query for each new row
}
This code returns the following error:
"System.Data.SqlClient.SqlException (0x80131904): Invalid column name 'a51'"
a51 is the correct value inside of the record I'm looking for in the EstablishmentCode column of the Establishments table. Account ID is used to find all entries on the Establishments table with that account ID and populate a dataset with Establishment Code values. Account ID value comes from a session variable. Then I use each of these values in a loop where each iteration calls a datareader while loop. Hope I explained this clearly, but I would gladly clarify more if needed. Here's my code.
myConnection.Open();
SqlCommand getEst = new SqlCommand("SELECT EstablishmentCode FROM Establishments WHERE AccountID = " + ID, myConnection);
da = new SqlDataAdapter(getEst);
ds = new DataSet();
da.Fill(ds);
int maxrows = ds.Tables[0].Rows.Count;
for (int x = 0; x < maxrows; x++)
{
getPhones = new SqlCommand("SELECT * FROM DispatcherPhones WHERE EstablishmentCode = " + ds.Tables[0].Rows[x].ItemArray.GetValue(0).ToString(), myConnection);
myReader = getPhones.ExecuteReader();
while (myReader.Read())
{
Response.Write("<section id='phone" + myReader["Phone"].ToString() + "' style='padding:20px'>");
Response.Write("<section>Phone Number<br><div class='phone'>" + myReader["Phone"].ToString() + "</div></section>");
Response.Write("<section>Location Code<br><div class='name'>" + myReader["EstablishmentCode"].ToString() + "</div></section>");
Response.Write("<section>Active<br><div class='name'>" + myReader["Active"].ToString() + "</div></section>");
Response.Write("<section class='flex phoneButtonSection'>");
Response.Write("<button type=\"button\" onclick=\"showPhoneForm('" + myReader["ID"].ToString() + "');\">CHANGE</button>");
Response.Write("<button type=\"button\" onclick=\"deletePhones('" + myReader["ID"].ToString() + "');\">DELETE</button>");
Response.Write("</section>");
Response.Write("</section>");
}
myReader.Close();
}
myReader.Close();
myConnection.Close();
String literals in SQL are denoted by single quotes ('s) which are missing for your value:
getPhones = new SqlCommand
("SELECT * " +
"FROM DispatcherPhones
"WHERE EstablishmentCode = '" +
// Here -------------------^
ds.Tables[0].Rows[x].ItemArray.GetValue(0).ToString() +
"'" // And here
, myConnection);
Mandatory comment: concatinating strings in order to create SQL statements may leave your code exposed to SQL injection attacks. You should consider using prepared statements instead.
In c# Windows Forms:
I'm having trouble adding a sql query result as text to a ToolStripMenuItem.Text.
The ToolStripMenuItem title should be, the company + how many orders there are in the sql table for this company which should update every x secounds.
Every 5 seconds it adds the query result to the text. My problem is that is "adds" it.
After the first 5 seconds it looks OK "rexton 1" but 5 seconds after it shows "rexton 1 1" and so on...
Here is my code:
//Rexton ordre klar til bestilling
SqlConnection con = new SqlConnection(#"Data Source=" + globalvariables.hosttxt + "," + globalvariables.porttxt + "\\SQLEXPRESS;Database=ha;Persist Security Info=false; UID='" + globalvariables.user + "' ; PWD='" + globalvariables.psw + "'");
SqlCommand command = con.CreateCommand();
command.CommandText = "SELECT COUNT(*) from bestillinger WHERE firma = #rexton and udlevering BETWEEN #date and #dateadd";
command.Parameters.AddWithValue("#bernafon", "Bernafon");
command.Parameters.AddWithValue("#gn_resound", "GN Resound");
command.Parameters.AddWithValue("#oticon", "Oticon");
command.Parameters.AddWithValue("#phonak", "Phonak");
command.Parameters.AddWithValue("#rexton", "Rexton");
command.Parameters.AddWithValue("#siemens", "Siemens");
command.Parameters.AddWithValue("#widex", "Widex");
con.Open();
command.ExecuteNonQuery();
string result = command.ExecuteScalar().ToString();
con.Close();
if (result != "0")
{
rextonToolStripMenuItem.Text = rextonToolStripMenuItem.Text + " " + result;
rextonToolStripMenuItem.ForeColor = System.Drawing.ColorTranslator.FromHtml("#FF1919");
}
it is because you are setting rextonToolStripMenuItem.Text to rextonToolStripMenuItem.Text + " " + result which is appending to previous text
either set text to blank and set it again or just say
rextonToolStripMenuItem.Text = "rexton " + result
I have a control that creates textboxes dynamically.
For each of these textboxes I want to make an insert to my SQL database.
For example I have 3 textboxes with id FlottenID1, FlottenID2, FlottenID3.
Every TextBox has default of FlottenID and then comes the number 1,2,3,4,5 depending on how many I have.
Now I need help how can I say in my insert Loop that it should start with inserting FlottenID1 and then next time it will be FlottenID2 and so on...
My other id's always have the same Name so there it is no problem. There I can only write Cust.text for example. Hope you understand what I'm searching for. Thanks!
protected void btnGenerateControl_Click(object sender, EventArgs e)
{
int Count = Convert.ToInt32(Qty.Text);
for(int i =1; i <= Count; i++)
{
Label lbl = new Label();
TextBox txtbox = new TextBox();
lbl.Text = " Flotten ID Velo Nr" + (i).ToString() + " ";
//txtbox.Text = "Textbox - " + i.ToString();
txtbox.ID = "FlottenID" + i.ToString();
txtbox.EnableViewState = true;
pnlTextBoxes.Controls.Add(lbl);
pnlTextBoxes.Controls.Add(txtbox);
pnlTextBoxes.Controls.Add(new LiteralControl("<br /><br />"));
}
}
protected void btnAddOrder_Click(object sender, EventArgs e)
{
int Count = Convert.ToInt32(Qty.Text);
for (int i = 1; i <= Count; i++)
{
String query = "insert into Orders (CustID, OrderDate, Time, ProductID, ProjectID, Status, FlottenID)values('" + CustID.Text + "','" + OrderDate.Text + "','" + Time.Text + "','" + ProductID.Value + "','" + ProjectID.Value + "','" + Status.Value + "','" + " FlottenID " + "')";
String query1 = "commit;";
DataLayer.DataConnector dat = new DataLayer.DataConnector("Provider=SQLOLEDB; data source=****;database=***;user ID=event;password=****; Persist Security Info=False");
dat.DataInsert(query);
dat.DataInsert(query1);
}
}
I think you asked same question which i gave the solution to that.Anyway I give the code now..
Write the below code in btnGenerateControl_Click1 Event(below For Loop)
pnlTextBoxes.Controls.Add(new LiteralControl("<input id='txtbox' name='FlottenID" + i + "'type='text' />"));
pnlTextBoxes.Controls.Add(new LiteralControl("<br />"));
This generates TextBox ids Like (FlottenID1,FlottenID2,..........Based on the For Loop)